实例详解Spring JDBC事务管理
Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction management),为不同的事务实现提供了一致的编程模型,这节以JDBC事务为例,介绍Spring的事务管理。
事务是一组原子(Atomic)操作的工作单元,以数据库存取的实例来说,就是一组SQL指令,这一组SQL指令必须全部执行成功,若因为某个原因未全部执行成功(例如其中一行SQL有错误),则先前所有执行过的SQL指令都会被撤消。
事务还必须保持所参与资源的一致性(Consistent),例如在银行账户的例子中,两个账户的转账金额,B账户取款的金额不能大于A账户的存款金额。每个事务彼此之间必须是隔离的(Isolated),例如在A账户中可能有两笔事务,同时进行存款与提款的动作,两个事务基本上不需意识到彼此的存在。事务还必须是可持续的(Durable),在某一笔事务之后,这笔事务必须是被记录下来的。
在 insert()方法中使用了DataSourceTransactionManager来进行事务管理,如果发生了异常,则catch区块中会进行事务的Rollback,在insert() 方法中故意写入错误的SQL(注意INSERT方法少写了一个T),因此实际上数据并不会被储存至数据库中。
要使用MySQL数据库进行事务处理,必须建立支持事务的表格类型,例如InnoDB的表格类型,这里用来建立表格的SQL如下所示:
如果发生了异常,则会进行Rollback,否则提交事务,如果没有回传值,则也可以使用TransactionCallbackWithoutResult:
TransactionProxyFactoryBean需要一个TransactionManager,由于这里使用的是JDBC,所以使用 DataSourceTransactionManager,TransactionProxyFactoryBean是个代理对象,"target" 属性指定要代理的对象,事务管理会自动介入指定的方法前后,这里使用 "transactionAttributes" 属性指定,"insert*" 表示指定方法名称以insert开头的都要纳入事务管理,您也可以指定方法全名,如果在方法执行过程中发生错误,则所有先前的操作自动撤回,否则正常提交。
在"insert*" 等方法上指定了 "PROPAGATION_REQUIRED",表示在目前的事务中执行操作,如果事务不存在就建立一个新的,相关的常数意义都可以在API文件的 TransactionDefinition接口中找到。您可以加上多个事务定义,中间使用逗号 "," 区隔,例如可以加上只读,或者是指定某个异常发生时撤回操作:
PROPAGATION_REQUIRED,readOnly,-MyCheckedException
MyCheckedException前面加上 "-" 时,表示发生指定异常时撤消操作,如果前面加上 "+",表示发生异常时立即提交。
由于"userDAO"被"userDAOProxy"代理了,所以要做的是取得"userDAOProxy",而不是"userDAO",例如:
DeclarativeTransactionDemo SpringDAODemo.java
您也可以设置不同的TransactionInterceptor来得到更多的管理细节,例如:
同样的,由于不再于设置文件中设置代理对象,所以直接取得"userDAO"实例进行操作即可。
不好意思。首先说下,这个也是我从网上贴过来的。
至于你说的不用迭代器。那就要看情况了, 首先他是个接口,当我们知道其实现类的时候通过都是得通过统一接口调用的。
那这里虽然是List,那如果是ArrayList的时候用for去遍历List当然没有问题。但是如果是LinkedList的时候和就存在一个效率的问题了。比如for(i=0; i<linkedList.size(); i++){ System.out.println(linkedList.get(i));}
我们知道LinkedList在做插入删除时操作是比较快的。但是快速通过下标定位的话就不是它的强项,是ArrayList的强项了。所以上面的代码不仅遍历了一遍list。同时在取相应下标的值的时候还是得从链表头开始找。 3 楼 yknife 2012-03-08 wensiqun 写道那这里虽然是List,那如果是ArrayList的时候用for去遍历List当然没有问题。但是如果是LinkedList的时候和就存在一个效率的问题了。
谢谢你的不吝赐教,刚刚查了下资料,并且写了程序亲测了一下,发现用for遍历和用Iterator遍历LinkedList的时候,效率是有明显区别的,Iterator的优势明显(8ms vs 600ms+)。
而且Iterator还是通用接口,不管是LinkedList还是ArrayList都有自己实现,在编码时候统一使用这一接口,可以试代码的可重用度变高(改变List类型时),而不需因为效率问题,大量的更改遍历代码的方式。