Spring的事务管理难点剖析(1):DAO和事务管理的牵绊(二)

2014-11-24 08:46:59 · 作者: · 浏览: 1
ref="dataSource"/>

20

运行UserJdbcWithoutTransManagerService,在控制台上打出如下的结果:

引用

defaultAutoCommit:true
score:30


在jdbcWithoutTx.xml中,没有配置任何事务管理器,但是数据已经成功持久化到数据库中。在默认情况下,dataSource数据源的 autoCommit被设置为true——这也意谓着所有通过JdbcTemplate执行的语句马上提交,没有事务。如果将dataSource的 defaultAutoCommit设置为false,再次运行UserJdbcWithoutTransManagerService,将抛出错误,原 因是新增及更改数据的操作都没有提交到数据库,所以代码清单10-1④处的语句因无法从数据库中查询到匹配的记录而引发异常。
对于强调读速度的应用,数据库本身可能就不支持事务:如使用MyISAM引擎的MySQL数据库。这时,无须在Spring应用中配置事务管理器,因为即使配置了,也是没有实际用处的。

Hibernate访问数据库

对于Hibernate来说,情况就有点复杂了。因为Hibernate的事务管理拥有其自身的意义,它和Hibernate一级缓存在密切的关系:当我 们调用Session的save、update等方法时,Hibernate并不直接向数据库发送SQL语句,只在提交事务(commit)或flush 一级缓存时才真正向数据库发送SQL。所以,即使底层数据库不支持事务,Hibernate的事务管理也是有一定好处的,不会对数据操作的效率造成负面影 响。所以,如果是使用Hibernate数据访问技术,没有理由不配置HibernateTransactionManager事务管理器。

但是,不使用Hibernate事务管理器,在Spring中,Hibernate照样也可以工作,来看下面的例子:


01 package com.baobaotao.withouttx.hiber;

02

03 import org.springframework.beans.factory.annotation.Autowired;

04 import org.springframework.core.io.ClassPathResource;

05 import org.springframework.core.io.Resource;

06 import org.springframework.jdbc.core.JdbcTemplate;

07 import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

08 import org.springframework.stereotype.Service;

09 import org.springframework.context.ApplicationContext;

10 import org.springframework.context.support.ClassPathXmlApplicationContext;

11 import org.springframework.orm.hibernate3.HibernateTemplate;

12 import org.apache.commons.dbcp.BasicDataSource;

13 import org.springframework.test.jdbc.SimpleJdbcTestUtils;

14

15 import com.baobaotao.User;

16

17 @Service("hiberService")

18 public class UserHibernateWithoutTransManagerService {

19

20 @Autowired

21 private HibernateTemplate hibernateTemplate;

22

23 public void addScore(String userName,int toAdd){

24 User user = hibernateTemplate.get(User.class,userName);

25 user.setScore(user.getScore()+toAdd);

26 hibernateTemplate.update(user);

27 }

28

29 public static void main(String[] args) {

30 ApplicationContext ctx = new

31 ClassPathXmlApplicationContext("com/baobaotao/withouttx/hiber/hiberWithoutTx.xml");

32 UserHibernateWithoutTransManagerService service =

33 (UserHibernateWithoutTransManagerService)ctx.getBean("hiberService");

34

35 JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean("jdbcTemplate");

36 BasicDataSource basicDataSource = (BasicDataSource)jdbcTemplate.getDataSource();

37

38 //①检查数据源autoCommit的设置

39 System.out.println("autoCommit:"+ basicDataSource.getDefaultAutoCommit());

40

41 //②插入一条记录,初始分数为10

42 jdbcTemplate.execute("INSERT INTO t_user(user_name,password,score,last_logon_time)

43 VALUES('tom','123456',10,"+System.currentTimeMillis()+")");

44

45 //③调用工作在无事务环境下的服务类方法,将分数添加20分

46 service.addScore("tom",20);

47

48 //④查看此时用户的分数

49 int score = jdbcTemplate.queryForInt(

50 "SELECT score FROM t_u