UserServiceImpl就可以看做是A事务

AccountServiceImpl就可以看做是B事务

项目中的所有事务,必须添加到业务逻辑上。

若A事务要包含进B事务,怎么包含?

UsersServiceImpl.java

  1. @Autowired
  2. AccountService accountService;
  1. @Override
  2. public int insertUsers(Users users) {
  3. // return usersMapper.insertUsers(users);
  4. int num = usersMapper.insertUsers(users);
  5. System.out.println(num);
  6. //调用账户的增加操作,调用的账户的业务逻辑层的功能
  7. num = accountService.insertAccount(new Account(300,"王五","账户好的呢"));
  8. return num;
  9. }

事务传播特性解析(重点)

UsersServiceImpl AccountServiceImpl(抛异常) 预测结果
场景一 无事务 无事务 users=OK;account=OK
场景二 无事务 REQUIRED users=OK;account=NO
场景三 REQUIRED 无事务 users=NO;account=NO
场景四 REQUIRED NOT_SUPPORTED users=NO;account=OK
场景五 REQUIRED SUPPORTS users=NO;account=NO
场景六 REQUIRED REQUIRES_NEW users=NO;account=NO
场景七 REQUIRED REQUIRED users=NO;account=NO
场景八 REQUIRED NEVER users=NO;account=NO
  1. #清空表中数据
  2. USE ssm;
  3. DELETE FROM users;
  4. DELETE FROM accounts;

场景一
  1. @Test
  2. public void testUsers(){
  3. //创建容器并启动
  4. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_service.xml");
  5. //取出UsersServiceImpl(永远是接口接(干活))
  6. UsersService uService = (UsersService) ac.getBean("usersServiceImpl");
  7. int num = uService.insertUsers(new Users(1,"张三","123"));
  8. System.out.println(num);
  9. }
  1. 1
  2. 添加用户成功,num=1
  3. java.lang.ArithmeticException: / by zero

查看表

users

userid uname upass
1 张三 123

accounts

aid aname acountent
300 王五 账户好的呢

场景二

AccountServiceImpl.java

  1. package com.chentianyu.service.impl;
  2. import com.chentianyu.mapper.AccountMapper;
  3. import com.chentianyu.pojo.Account;
  4. import com.chentianyu.service.AccountService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import org.springframework.transaction.annotation.Propagation;
  8. import org.springframework.transaction.annotation.Transactional;
  9. @Service
  10. @Transactional(propagation = Propagation.REQUIRED)/*REQUIRED传播特性*/
  11. public class AccountServiceImpl implements AccountService {
  12. //但凡是业务逻辑层的实现类,一定会有数据访问层的对象
  13. @Autowired
  14. AccountMapper accountMapper;
  15. @Override
  16. public int insertAccount(Account account) {
  17. int num = 0;
  18. num = accountMapper.insertAccount(account);
  19. System.out.println("添加用户成功,num="+num);
  20. //手动抛出异常
  21. System.out.println(1/0);//出现错误的时候我们不希望数据插入进数据库
  22. return num;
  23. }
  24. }

为了查看方便,mybatis主配置文件添加

  1. <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  2. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  3. <configuration>
  4. <settings>
  5. <setting name="logImpl" value="STDOUT_LOGGING"/>
  6. </settings>
  7. </configuration>
  1. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4a9cc6cb] will not be managed by Spring
  2. ==> Preparing: insert into users values(?,?,?)
  3. ==> Parameters: 1(Integer), 张三(String), 123(String)
  4. <== Updates: 1
  5. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1698fc68]
  6. 1
  7. Creating a new SqlSession
  8. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5149f008]
  9. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4a9cc6cb] will be managed by Spring
  10. ==> Preparing: insert into accounts values(?,?,?)
  11. ==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
  12. <== Updates: 1
  13. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5149f008]
  14. 添加用户成功,num=1

字面上看是增加成功的

我们看一下数据库中的数据

users

userid uname upass
1 张三 123

accounts(有事务)

aid aname acountent

场景三

UsersServiceImpl.java

  1. @Service //交给spring去创建对象
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. public class UsersServiceImpl implements UsersService {...}

AccountServiceImpl.java

  1. @Service
  2. public class AccountServiceImpl implements AccountService {...}
  1. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7a56812e] will be managed by Spring
  2. ==> Preparing: insert into users values(?,?,?)
  3. ==> Parameters: 1(Integer), 张三(String), 123(String)
  4. <== Updates: 1
  5. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]
  6. 1
  7. Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605] from current transaction
  8. ==> Preparing: insert into accounts values(?,?,?)
  9. ==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
  10. <== Updates: 1
  11. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]
  12. 添加用户成功,num=1
  13. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]
  14. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]
  15. java.lang.ArithmeticException: / by zero

貌似都添加成功了

users(有事务)

userid uname upass

accounts

aid aname acountent

accounts外层(users)有事务,被合并到外边的事务中了,所以也裹上了事务的处理

场景四

UsersServiceImpl.java

  1. @Service //交给spring去创建对象
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. public class UsersServiceImpl implements UsersService {...}

AccountServiceImpl.java

  1. @Service
  2. @Transactional(propagation = Propagation.NOT_SUPPORTED)
  3. public class AccountServiceImpl implements AccountService {...}
  1. Creating a new SqlSession
  2. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
  3. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
  4. ==> Preparing: insert into users values(?,?,?)
  5. ==> Parameters: 1(Integer), 张三(String), 123(String)
  6. <== Updates: 1
  7. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
  8. 1
  9. Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
  10. Creating a new SqlSession
  11. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
  12. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
  13. ==> Preparing: insert into accounts values(?,?,?)
  14. ==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
  15. <== Updates: 1
  16. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
  17. 添加用户成功,num=1
  18. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
  19. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
  20. Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
  21. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
  22. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
  23. java.lang.ArithmeticException: / by zero

貌似都添加成功了

users

userid uname upass

accounts

aid aname acountent
300 王五 账户好的呢

场景五

UsersServiceImpl.java

@Service    //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}

AccountServiceImpl.java

@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==>  Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
==>  Preparing: insert into accounts values(?,?,?)
==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
添加用户成功,num=1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]

java.lang.ArithmeticException: / by zero

貌似都添加成功了

users(有事务)

userid uname upass

accounts(跟前面的保持一致,”你说的都对,都听你的”)

aid aname acountent

场景六

UsersServiceImpl.java

@Service    //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}

AccountServiceImpl.java

@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==>  Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
==>  Preparing: insert into accounts values(?,?,?)
==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
添加用户成功,num=1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]

java.lang.ArithmeticException: / by zero

貌似都添加成功了

users(有事务)

userid uname upass

accounts(运行的机制不一样,但是你是包在事务中的;一出错立马回滚)

aid aname acountent

场景七

UsersServiceImpl.java

@Service    //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}

AccountServiceImpl.java

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==>  Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
==>  Preparing: insert into accounts values(?,?,?)
==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
添加用户成功,num=1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]

java.lang.ArithmeticException: / by zero

貌似都添加成功了

users(有事务)

userid uname upass

accounts

aid aname acountent

场景八

UsersServiceImpl.java

@Service    //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}

AccountServiceImpl.java

@Service
@Transactional(propagation = Propagation.NEVER)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==>  Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]

org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'

NEVER: 你不能把我包在事务里,你敢,我就让程序崩溃