知方号

知方号

关于加@Transactional注解的方法之间调用,事务是否生效的问题<怎样判断新生事物对错的方法>

关于加@Transactional注解的方法之间调用,事务是否生效的问题

1. 不同类之间的方法调用,如类A的方法a()调用类B的方法b(),这种情况事务是正常起作用的。只要方法a()或b()配置了事务,运行中就会开启事务,产生代理。

若两个方法都配置了事务,两个事务具体以何种方式传播,取决于设置的事务传播特性。

2. 同一个类内方法调用:重点来了,同一个类内的方法调用就没那么简单了,假定类A的方法a()调用方法b()

同一类内方法调用,无论被调用的b()方法是否配置了事务,此事务在被调用时都将不生效。

看一个例子:

代码语言:javascript复制@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserDao userDao; public int insertUser(User user) { userDao.insertUser(user); // 调用同类方法 this.selectUser(user.getId()); return 1; } @Transactional public String selectUser(int id) { throw new RuntimeException(); //return userDao.selectUser(id); } public int updateUser(User user) { return userDao.updateUser(0, user); } }

service层中,insertUser()方法没有配置事务,selectUser()配置了事务,在insertUser()中调用selectUser()时,查看日志如下:

代码语言:javascript复制[DEBUG][2018-02-22 11:00:32] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) drop table if exists user Hibernate: drop table if exists user[DEBUG][2018-02-22 11:00:32] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) create table user (id integer not null auto_increment, createdDate datetime, email varchar(255), name varchar(20) not null, password varchar(255), phone varchar(255), updatedDate datetime, primary key (id)) Hibernate: create table user (id integer not null auto_increment, createdDate datetime, email varchar(255), name varchar(20) not null, password varchar(255), phone varchar(255), updatedDate datetime, primary key (id))[INFO][2018-02-22 11:00:32] org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:406) HHH000230: Schema export complete [DEBUG][2018-02-22 11:00:32] org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:1073) Checking 0 named HQL queries [DEBUG][2018-02-22 11:00:32] org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:1096) Checking 0 named SQL queries [DEBUG][2018-02-22 11:00:32] org.hibernate.stat.internal.StatisticsInitiator.initiateServiceInternal(StatisticsInitiator.java:110) Statistics initialized [enabled=false] [INFO][2018-02-22 11:00:33] org.springframework.orm.hibernate4.HibernateTransactionManager.afterPropertiesSet(HibernateTransactionManager.java:360) Using DataSource [com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1hge15x9t1g0fr98s704x1|72d1ad2e, dataSourceName -> 1hge15x9t1g0fr98s704x1|72d1ad2e ]] of Hibernate SessionFactory for HibernateTransactionManager [DEBUG][2018-02-22 11:00:33] org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:228) Executing identity-insert immediately [DEBUG][2018-02-22 11:00:33] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) insert into user (createdDate, email, name, password, phone, updatedDate) values (?, ?, ?, ?, ?, ?) Hibernate: insert into user (createdDate, email, name, password, phone, updatedDate) values (?, ?, ?, ?, ?, ?)[DEBUG][2018-02-22 11:00:33] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:212) Obtaining JDBC connection [DEBUG][2018-02-22 11:00:33] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:218) Obtained JDBC connection [DEBUG][2018-02-22 11:00:33] org.hibernate.id.IdentifierGeneratorHelper.getGeneratedIdentity(IdentifierGeneratorHelper.java:93) Natively generated identity: 1 [DEBUG][2018-02-22 11:00:33] org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:267) parse() - HQL: select name from com.wcl.pojo.User u where u.id = ? [DEBUG][2018-02-22 11:00:33] org.hibernate.hql.internal.ast.QueryTranslatorImpl.showHqlAst(QueryTranslatorImpl.java:285) --- HQL AST ---

可见没有开启事务,因此selectUser()的事务配置没有生效,抛异常后也不会回滚。

另一个例子:方法a()配置了事务,此时b()的事务虽然不生效,但a()的事务生效,对于b()中抛出的异常也会回滚。

代码语言:javascript复制[DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) drop table if exists user Hibernate: drop table if exists user[DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) create table user (id integer not null auto_increment, createdDate datetime, email varchar(255), name varchar(20) not null, password varchar(255), phone varchar(255), updatedDate datetime, primary key (id)) Hibernate: create table user (id integer not null auto_increment, createdDate datetime, email varchar(255), name varchar(20) not null, password varchar(255), phone varchar(255), updatedDate datetime, primary key (id))[INFO][2018-02-22 11:08:50] org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:406) HHH000230: Schema export complete [DEBUG][2018-02-22 11:08:50] org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:1073) Checking 0 named HQL queries [DEBUG][2018-02-22 11:08:50] org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:1096) Checking 0 named SQL queries [DEBUG][2018-02-22 11:08:50] org.hibernate.stat.internal.StatisticsInitiator.initiateServiceInternal(StatisticsInitiator.java:110) Statistics initialized [enabled=false] [INFO][2018-02-22 11:08:50] org.springframework.orm.hibernate4.HibernateTransactionManager.afterPropertiesSet(HibernateTransactionManager.java:360) Using DataSource [com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1hge15x9t1g0qf4c3bcmx8|399f45b1, dataSourceName -> 1hge15x9t1g0qf4c3bcmx8|399f45b1 ]] of Hibernate SessionFactory for HibernateTransactionManager [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:212) Obtaining JDBC connection [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:218) Obtained JDBC connection [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:158) begin [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:69) initial autocommit status: true [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:71) disabling autocommit [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:228) Executing identity-insert immediately [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) insert into user (createdDate, email, name, password, phone, updatedDate) values (?, ?, ?, ?, ?, ?) Hibernate: insert into user (createdDate, email, name, password, phone, updatedDate) values (?, ?, ?, ?, ?, ?)[DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:212) Obtaining JDBC connection [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:218) Obtained JDBC connection [DEBUG][2018-02-22 11:08:50] org.hibernate.id.IdentifierGeneratorHelper.getGeneratedIdentity(IdentifierGeneratorHelper.java:93) Natively generated identity: 1 [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:203) rolling back [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:164) rolled JDBC Connection [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.releaseManagedConnection(JdbcTransaction.java:126) re-enabling autocommit [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.releaseConnection(LogicalConnectionImpl.java:232) Releasing JDBC connection [DEBUG][2018-02-22 11:08:50] org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.releaseConnection(LogicalConnectionImpl.java:250) Released JDBC connection Exception in thread "main" java.lang.RuntimeExceptionat com.wcl.service.UserServiceImpl.selectUser(UserServiceImpl.java:26)at com.wcl.service.UserServiceImpl.insertUser(UserServiceImpl.java:20)

3. 不生效的原因?

有几篇文章探究了事务这个特性的原因,spring

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。