为什么用spring

遇到这个问题时,我突然没有了头绪,使用spring已经接近三年了,也阅读了不少spring的源代码,从中获取了不少的编码灵感,但是却忽略了这个最根本的问题,为什么我们需要spring?很多时候我们就是这样走着走着,确忘记了自己为什么要走这条路…… 
如果走得太远,会不会忘了当初为什么出发? 
总结一下,备忘。 
spring 的特点: 

    1 spring 提供的是管理你的业务对象的方法。 

    2 spring既是全面的,又是模块化的,我们可以选择使用spring中的某个独立的部分。 
    
    3 spring的设计从一开始就是要帮助你编写易于测试的代码(所有的业务对象都是可以独   立于容器运行的,spring提供了大量的mock对象来实现对容器的隔离),是使用测试驱动开发   的工程的理想框架。 

    4 spring不会给你的工程添加对其他框架的依赖。 


spring带给我们的好处: 
    1. spring能够有效地组织中间层对象。 
    
    2. spring能够消除在很多工程中常见的对singleton的过多使用。 
    
    3. 通过一种在不同应用程序和项目之间一致的方法处理配置文件,spring能够消除各种各样自定义格式的属性文件的需要。 
    
    4. 把对面向接口编程而不是面对类编程的代价减少到几乎没有,spring能够促成良好的编程习惯。 
    
    5. spring被设计为让使用它创建的应用尽可能少的依赖于它的APIs。 
    
    6. spring能够使EJB的使用成一个实现选择,而不是必然选择。你能够选择用POJO或者locale EJBs 来实现业务接口,确不影响调用代码。 
    
    7. spring 帮你解决许多问题而无需使用EJB,spring能够提供一种EJB的替换物。如spring能够使用AOP提供声明式事务管理而不通过EJB容器。 

spring中事务管理中的事务传播机制

PROPAGATION_REQUIRES_NEW starts a new, independent "inner" transaction for the given scope. This transaction will be committed or rolled back completely independent from the outer transaction, having its own isolation scope, its own set of locks, etc. The outer transaction will get suspended at the beginning of the inner one, and resumed once the inner one has completed. 

PROPAGATION_REQUIRES_NEW会在当前运行的范围内创建一个全新的内部事务,这个的事务会独立地被提交或回滚(完全独立于外部事务),它拥有自己的隔离级别,以及锁等等。当内部事务被执行时,外部事务会被挂起,知道内部事务结束时才会继续执行。 

Such independent inner transactions are for example used for id generation through manual sequences, where the access to the sequence table should happen in its own transactions, to keep the lock there as short as possible. The goal there is to avoid tying the sequence locks to the (potentially much longer running) outer transaction, with the sequence lock not getting released before completion of the outer transaction. 
这种独立的内部事务会被诸如从序列生成ID的应用中,从序列取得id的动作应该发生在自己的事务内部,并且保持对这个sequence表的锁的时间越短越好。这么做是为了避免在获得ID以后可能仍然在很长时间内持有这个sequence表的锁(外部事务仍在运行中)。 

PROPAGATION_NESTED on the other hand starts a "nested" transaction, which is a true subtransaction of the existing one. What will happen is that a savepoint will be taken at the start of the nested transaction. íf the nested transaction fails, we will roll back to that savepoint. The nested transaction is part of of the outer transaction, so it will only be committed at the end of of the outer transaction. 
PROPAGATION_NESTED启动了一次嵌套的事务(一个当前事务的子事务),在内部嵌套事务开始时,会保留一个保存点(savepoint),如果内部嵌套事务失败,将会回滚到savepoint处,内部嵌套事务是外部事务的一部分,所以只有在外部事务完成时才会被提交。 

Nested transactions essentially allow to try some execution subpaths as subtransactions: rolling back to the state at the beginning of the failed subpath, continuing with another subpath or with the main execution path there - all within one isolated transaction, and not losing any previous work done within the outer transaction. 
嵌套事务可以满足子事务“多路执行”的需求:回滚到失败的内部嵌套事务开始的地方,然后执行另外的一个内部嵌套事务,或者继续执行主事务-上面提及的事务都是独立的,不会丢失外部事务所作的修改。 

For example, consider parsing a very large input file consisting of account transfer blocks: The entire file should essentially be parsed within one transaction, with one single commit at the end. But if a block fails, its transfers need to be rolled back, writing a failure marker somewhere. You could either start over the entire transaction every time a block fails, remembering which blocks to skip - or you mark each block as a nested transaction, only rolling back that specific set of operations, keeping the previous work of the outer transaction. The latter is of course much more efficient, in particular when a block at the end of the file fails. 

例如,分块传输一个很大的文件,整个文件的传输应该放在一个事务内部,在文件传输完成后提交事务。如果一个文件块传输失败了,就需要在某个地方写一个失败标记,然后重新传这个文件块,你可以在每次传输一个文件块失败时重新开始事务,然后记住那些块已经成功传输了,忽略即可-或者你可以把每个文件块的传输作为一个内部嵌套事务,只回滚失败的事务,保存前面事务的更改结果,当然这种方法要有效得多,想像一个最后一个文件块出错的情形。

离我梦想中的公司如此之近

从一开始的电话沟通,到收到homework,好不容易周日休息一天,把homework完成,发出去,直到收到回复, HR MM给我的反馈一直都很不错,约好13号上午电话面试,刚好那天是我生日,刚好前一天晚上感冒了,昏昏沉沉呢地就去接电话了。 面试我的刚好就是之前我一直很关注的一个blogger,也是一个ThoughtWorker,能力很强的一个人。

在简单地介绍了自己的项目经验以后,问题不断地从电话那头抛过来, 一开始问的都是一些技术上的问题,在回答这些问题时,我还是很有自信的,回答得都不错,后面的问题重点慢慢转移到项目运作过程上, 感觉ThoughtWorker对H公司(我现在所在的公司)的项目流程,工作方式还是很了解的,不断地问一些我在项目中遇到的一些棘手的问题,而且基本上都是人的问题,沟通、协调的问题, 比如,当你在开发过程中所坚持的原则与项目进度发生剧烈冲突的时候,你该如何处理? 这样的问题我在现在的项目组里经常遇到,除了抱怨几句,我好像也没有提出什么建设性的建议,现在,咨询师门把这个问题抛给我,我当然也不会提出什么有效地的方案,到这时候,才发现自己表述能力的匮乏。 半个小时后,面试结束了,我对自己的表现很不满意。回想起来我所欠缺的,不是技术能力,而是沟通的技巧、合适的工作方法,以及流畅的表达能力。 冷静下来,我开始回想起上次跳槽前我的状态,和现在的我何其相似:对现有工作方式的厌倦,想象着能够象读过一些书中描述的那样的软件开发模式进行开发,周围有一群对软件开发有狂热爱好的同事。是不是我所向往的那个地方只是个漂亮的象牙塔呢?我到底想要什么样的工作?

先说下我对软件开发过程的理解:软件开发是纯粹的脑力劳动,因此,人的因素很关键,我对好的软件的理解就是:用最少、最简洁的结构的代码完成客户需求,软件开发就像是艺术创作,一个有着清晰、简洁的代码结构的软件,就是一件精美的青花瓷,而一个东拼西凑的仅仅完成了基本功能的软件,就是一个蹩脚的陶罐。我一直向着做出一件精美的青花瓷的方向努力,祝我成功。

即使这次没能去成TW公司,我也有了一次回想过去,总结自己的机会,以后要多做回顾,多做总结,这样才会成长,而不是在忙碌的加班中迷失了自己。

随便写写

该有半年没有来更新了,荒凉了好多。上半年里,发生了许许多多的事情: 去了两趟深圳,一次是去联通现场支持,学会了熬夜,喝啤酒吃烤肉;尝到正宗的潮汕砂锅粥;喜欢上了湖南菜;四个多年未见的小学同学竟然凑到一了起,聊天、吃饭。 第二次去深圳把上半年做的项目交接到深圳,尝到到了做项目经理的瘾,也尝到了做项目经理的痛;也抓狂到摔过手机;学会了狗刨;见到了的大海,并在海里游泳;吃海鲜吃到爽;吃到了正宗的炭烤鱼。 第二次从深圳回来后,竟然长得壮了一些,虽然体重还是有些不好意思公布,但至少有了些许胸肌、腹肌的轮廓,一憋气还能憋出四块腹肌呢,原本苗条的蛮腰,坐着时也能捏到一些赘肉了。 把助学贷款还完了,无债一阵轻,感觉不错。

从深圳回来,进入了一个新的项目组,这个项目的组织架构、SE能力感觉都比原来的要强一些,coder能力也都不错,有好多东西需要去学习,遗憾的是没有在上一个项目中时那种key man的感觉了 :)

把那台半旧的hasee电脑折腾了几下,就恢复正常了,给老婆当上网本用,谁知她还蛮花心思地在上面贴了些小玩意,嗬,还蛮好看的。

前两天入手一个M8,前一个是Nokia 水货机,经常以静默地形式罢工(来短信、电话时不振动也没响铃,无论设置何种模式都没作用),但是很耐摔,在深圳被摔得七零八落装起来照样用…… M8样子还真蛮帅的,就适合我这种没钱还想用iPhone的人秀下:

PS: M8主题设置成《机器人总动员》了,我和老婆都很喜欢这部电影,还特地买了个WALL-E模型摆在办公桌上。

久未动笔

自从进入新公司以后,就很少更新博客了,新公司的工作时间比以前长多了,加上白天无法上网,因此这里几乎要荒芜掉了。 回想来新公司的这五个多月里,从开始的懵懂到后来在项目中担任重要职责,我认识了太多东西包括对敏捷开发的实践。(待续)