(五)Spring 对事务的支持

第一节:事务简介

满足一下四个条件:

第一:原子性;

第二:一致性;

第三:隔离性;

第四:持久性;

-------------------------------------------------

首先我们认识一下我们为什么需要支持事务,我们事务管理的支持我们的程序会出现什么问题。

例子:

创建数据库:

CREATE TABLE `t_count` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) DEFAULT NULL,
`userName` varchar(20) COLLATE utf8_bin DEFAULT NULL,
`count` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

数据库数据:

 T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wishwzp.service.BankService;
 9 
10 public class T {
11 
12     private ApplicationContext ac;
13 
14     @Before
15     public void setUp() throws Exception {
16         ac=new ClassPathXmlApplicationContext("beans.xml");
17     }
18 
19     @Test
20     public void transferAccounts() {
21         BankService bankService=(BankService)ac.getBean("bankService");
22         //userId1向userId2转账了50元
23         bankService.transferAccounts(50, 1, 2);
24     }
25     
26 }

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans
 7         http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/aop
 9         http://www.springframework.org/schema/aop/spring-aop.xsd
10         http://www.springframework.org/schema/context
11         http://www.springframework.org/schema/context/spring-context.xsd">
12         
13     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
14         <property name="driverClassName" value="${jdbc.driverClassName}"/>
15         <property name="url" value="${jdbc.url}"/>
16         <property name="username" value="${jdbc.username}"/>
17         <property name="password" value="${jdbc.password}"/>
18     </bean>
19      
20     <context:property-placeholder location="jdbc.properties"/>
21     
22     <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
23         <constructor-arg ref="dataSource"></constructor-arg>
24     </bean>
25     
26     
27     <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
28         <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
29     </bean> 
30     
31     <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
32         <property name="bankDao" ref="bankDao"></property>
33     </bean> 
34     
35 </beans>

jdbc.properties:

1 jdbc.driverClassName=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
3 jdbc.username=root
4 jdbc.password=root

BankServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.dao.BankDao;
 4 import com.wishwzp.service.BankService;
 5 
 6 public class BankServiceImpl implements BankService{
 7 
 8     private BankDao bankDao;
 9     
10     public void setBankDao(BankDao bankDao) {
11         this.bankDao = bankDao;
12     }
13     
14     @Override
15     public void transferAccounts(final int count, final int userIdA, final int userIdB) {
16         
17         bankDao.outMoney(count, userIdA);
18         bankDao.inMoney(count, userIdB);    
19     }
20 }

BankService.java:

 1 package com.wishwzp.service;
 2 
 3 public interface BankService {
 4 
 5     /**
 6      * A向B转账count元
 7      * @param count
 8      * @param userIdA
 9      * @param userIdB
10      */
11     public void transferAccounts(int count,int userIdA,int userIdB);
12 }

BankDaoImpl.java:

 1 package com.wishwzp.dao.impl;
 2 
 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 5 
 6 import com.wishwzp.dao.BankDao;
 7 
 8 public class BankDaoImpl implements BankDao{
 9 
10     private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
11     
12     
13     public void setNamedParameterJdbcTemplate(
14             NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
15         this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
16     }
17     
18     @Override
19     public void inMoney(int money, int userId) {
20         // TODO Auto-generated method stub
21         String sql="update t_count set count=count+:money where userId=:userId";
22         MapSqlParameterSource sps=new MapSqlParameterSource();
23         sps.addValue("money", money);
24         sps.addValue("userId", userId);
25         namedParameterJdbcTemplate.update(sql,sps);
26     }
27 
28     @Override
29     public void outMoney(int money, int userId) {
30         // TODO Auto-generated method stub
31         String sql="update t_count set count=count-:money where userId=:userId";
32         MapSqlParameterSource sps=new MapSqlParameterSource();
33         sps.addValue("money", money);
34         sps.addValue("userId", userId);
35         namedParameterJdbcTemplate.update(sql,sps);
36     }
37 
38 }

BankDao.java:

1 package com.wishwzp.dao;
2 
3 public interface BankDao {
4 
5     public void inMoney(int money,int userId);
6     
7     public void outMoney(int money,int userId);
8 }

运行结果显示:

数据库中我们看到,我们的转账成功了。但是如果我们的程序中途出现了异常或者错误问题的话,那就不是这个样子的了。

例子:

将BankDaoImpl.java中的public void inMoney(int money, int userId) {}中的sql语句改成String sql="update t_count2 set count=count+:money where userId=:userId";其实根本就是没有t_count2这个表,所以程序就会出现问题,但是我们运行结果是这个样子的:

这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了

(这个时候我们就需要引入事物管理这个概念,将没有成功转账这个功能,事物滚回到之前的状态)

第二节:编程式事务管理

jdbc事务管理器:org.springframework.jdbc.datasource.DataSourceTransactionManager

Spring 提供的事务模版类:org.springframework.transaction.support.TransactionTemplate

-------------

我们在beans.xml文件中配置jdbc事物管理将数据源引入,并且配置Spring 提供的事务,在服务中配置property配置Spring 提供的事务

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wishwzp.service.BankService;
 9 
10 public class T {
11 
12     private ApplicationContext ac;
13 
14     @Before
15     public void setUp() throws Exception {
16         ac=new ClassPathXmlApplicationContext("beans.xml");
17     }
18 
19     @Test
20     public void transferAccounts() {
21         BankService bankService=(BankService)ac.getBean("bankService");
22         //userId1向userId2转账了50元
23         bankService.transferAccounts(50, 1, 2);
24     }
25     
26 }

beans.xml:

 1 package com.wishwzp.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wishwzp.service.BankService;
 9 
10 public class T {
11 
12     private ApplicationContext ac;
13 
14     @Before
15     public void setUp() throws Exception {
16         ac=new ClassPathXmlApplicationContext("beans.xml");
17     }
18 
19     @Test
20     public void transferAccounts() {
21         BankService bankService=(BankService)ac.getBean("bankService");
22         //userId1向userId2转账了50元
23         bankService.transferAccounts(50, 1, 2);
24     }
25     
26 }

 jdbc.properties:

1 jdbc.driverClassName=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
3 jdbc.username=root
4 jdbc.password=root

BankServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import org.springframework.transaction.TransactionStatus;
 4 import org.springframework.transaction.support.TransactionCallbackWithoutResult;
 5 import org.springframework.transaction.support.TransactionTemplate;
 6 
 7 import com.wishwzp.dao.BankDao;
 8 import com.wishwzp.service.BankService;
 9 
10 public class BankServiceImpl implements BankService{
11 
12     private BankDao bankDao;
13     
14     private TransactionTemplate transactionTemplate;
15     
16     public void setBankDao(BankDao bankDao) {
17         this.bankDao = bankDao;
18     }
19     
20     public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
21         this.transactionTemplate = transactionTemplate;
22     }
23 
24     @Override
25     public void transferAccounts(final int count, final int userIdA, final int userIdB) {
26         
27         transactionTemplate.execute(new TransactionCallbackWithoutResult() {
28             
29             @Override
30             protected void doInTransactionWithoutResult(TransactionStatus status) {
31                 // TODO Auto-generated method stub
32                 bankDao.outMoney(count, userIdA);
33                 bankDao.inMoney(count, userIdB);    
34             }
35         });
36     }
37 }

BankService.java:

 1 package com.wishwzp.service;
 2 
 3 public interface BankService {
 4 
 5     /**
 6      * A向B转账count元
 7      * @param count
 8      * @param userIdA
 9      * @param userIdB
10      */
11     public void transferAccounts(int count,int userIdA,int userIdB);
12 }

BankDaoImpl.java:

 1 package com.wishwzp.dao.impl;
 2 
 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 5 
 6 import com.wishwzp.dao.BankDao;
 7 
 8 public class BankDaoImpl implements BankDao{
 9 
10     private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
11     
12     
13     public void setNamedParameterJdbcTemplate(
14             NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
15         this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
16     }
17     
18     @Override
19     public void inMoney(int money, int userId) {
20         // TODO Auto-generated method stub
21         String sql="update t_count2 set count=count+:money where userId=:userId";
22         MapSqlParameterSource sps=new MapSqlParameterSource();
23         sps.addValue("money", money);
24         sps.addValue("userId", userId);
25         namedParameterJdbcTemplate.update(sql,sps);
26     }
27 
28     @Override
29     public void outMoney(int money, int userId) {
30         // TODO Auto-generated method stub
31         String sql="update t_count set count=count-:money where userId=:userId";
32         MapSqlParameterSource sps=new MapSqlParameterSource();
33         sps.addValue("money", money);
34         sps.addValue("userId", userId);
35         namedParameterJdbcTemplate.update(sql,sps);
36     }
37 
38 }

BankDao.java:

1 package com.wishwzp.dao;
2 
3 public interface BankDao {
4 
5     public void inMoney(int money,int userId);
6     
7     public void outMoney(int money,int userId);
8 }

运行结果显示:

这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了---------但是我们使用了编程式事务管理,这笔钱被事务滚回了。

虽然程序出现了问题,但是我们的赚钱也停止了,并没有任何损失。这就是使用事务的优点

 但是编程式事务管理也有也大的缺点,就是编程式事务管理侵入到业务逻辑代码中了。这并不是我们想要的。。。。

 所以我们一般使用的声明式事务管理。。。。。。。。。。。

第三节:声明式事务管理

 声明式事务管理分两种:

1,使用XML 配置声明式事务;

2,使用注解配置声明式事务;

1,使用XML 配置声明式事务;

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wishwzp.service.BankService;
 9 
10 
11 public class T {
12 
13     private ApplicationContext ac;
14 
15     @Before
16     public void setUp() throws Exception {
17         ac=new ClassPathXmlApplicationContext("beans.xml");
18     }
19 
20     @Test
21     public void transferAccounts() {
22         BankService bankService=(BankService)ac.getBean("bankService");
23         bankService.transferAccounts(50, 1, 2);
24     }
25 
26 }

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans
 8         http://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/aop
10         http://www.springframework.org/schema/aop/spring-aop.xsd
11         http://www.springframework.org/schema/tx
12         http://www.springframework.org/schema/tx/spring-tx.xsd
13         http://www.springframework.org/schema/context
14         http://www.springframework.org/schema/context/spring-context.xsd">
15         
16     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
17         <property name="driverClassName" value="${jdbc.driverClassName}"/>
18         <property name="url" value="${jdbc.url}"/>
19         <property name="username" value="${jdbc.username}"/>
20         <property name="password" value="${jdbc.password}"/>
21     </bean>
22     
23     <!-- jdbc事务管理器 -->
24     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
25         <property name="dataSource" ref="dataSource"></property>
26     </bean>
27     
28     <!-- 配置事务通知 -->
29     <tx:advice id="txAdvice" transaction-manager="transactionManager">
30         <tx:attributes>  
31             <tx:method name="*"/>  
32         </tx:attributes>  
33     </tx:advice>
34     
35     <!-- 配置事务切面 -->
36     <aop:config>
37         <!-- 配置切点 -->
38         <aop:pointcut id="serviceMethod" expression="execution(* com.wishwzp.service.*.*(..))" />
39         <!-- 配置事务通知 -->
40         <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
41     </aop:config>
42 
43      
44     <context:property-placeholder location="jdbc.properties"/>
45     
46     <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
47         <constructor-arg ref="dataSource"></constructor-arg>
48     </bean>
49     
50     
51     <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
52         <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
53     </bean> 
54     
55     <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
56         <property name="bankDao" ref="bankDao"></property>
57     </bean> 
58     
59 </beans>

jdbc.properties:

1 jdbc.driverClassName=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
3 jdbc.username=root
4 jdbc.password=123456

BankServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 
 4 import com.wishwzp.dao.BankDao;
 5 import com.wishwzp.service.BankService;
 6 
 7 
 8 public class BankServiceImpl implements BankService{
 9 
10     private BankDao bankDao;
11     
12     public void setBankDao(BankDao bankDao) {
13         this.bankDao = bankDao;
14     }
15     
16 
17     @Override
18     public void transferAccounts(int count, int userIdA, int userIdB) {
19         // TODO Auto-generated method stub
20                 // TODO Auto-generated method stub
21         bankDao.outMoney(count, userIdA);
22         bankDao.inMoney(count, userIdB);                
23     }
24 
25 }

BankService.java:

 1 package com.wishwzp.service;
 2 
 3 public interface BankService {
 4 
 5     /**
 6      * A向B转账count元
 7      * @param count
 8      * @param userIdA
 9      * @param userIdB
10      */
11     public void transferAccounts(int count,int userIdA,int userIdB);
12 }

BankDaoImpl.java:

 1 package com.wishwzp.dao.impl;
 2 
 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 5 
 6 import com.wishwzp.dao.BankDao;
 7 
 8 public class BankDaoImpl implements BankDao{
 9 
10     private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
11     
12     
13     public void setNamedParameterJdbcTemplate(
14             NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
15         this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
16     }
17     
18     @Override
19     public void inMoney(int money, int userId) {
20         // TODO Auto-generated method stub
21         String sql="update t_count2 set count=count+:money where userId=:userId";
22         MapSqlParameterSource sps=new MapSqlParameterSource();
23         sps.addValue("money", money);
24         sps.addValue("userId", userId);
25         namedParameterJdbcTemplate.update(sql,sps);
26     }
27 
28     @Override
29     public void outMoney(int money, int userId) {
30         // TODO Auto-generated method stub
31         String sql="update t_count set count=count-:money where userId=:userId";
32         MapSqlParameterSource sps=new MapSqlParameterSource();
33         sps.addValue("money", money);
34         sps.addValue("userId", userId);
35         namedParameterJdbcTemplate.update(sql,sps);
36     }
37 
38 }

BankDao.java:

1 package com.wishwzp.dao;
2 
3 public interface BankDao {
4 
5     public void inMoney(int money,int userId);
6     
7     public void outMoney(int money,int userId);
8 }

运行结果显示:

这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了---------但是我们使用了声明式事务管理,这笔钱被事务滚回了。

2,使用注解配置声明式事务;

 T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wishwzp.service.BankService;
 9 
10 
11 public class T {
12 
13     private ApplicationContext ac;
14 
15     @Before
16     public void setUp() throws Exception {
17         ac=new ClassPathXmlApplicationContext("beans.xml");
18     }
19 
20     @Test
21     public void transferAccounts() {
22         BankService bankService=(BankService)ac.getBean("bankService");
23         bankService.transferAccounts(50, 1, 2);
24     }
25     
26     
27 
28 }

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans
 8         http://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/aop
10         http://www.springframework.org/schema/aop/spring-aop.xsd
11         http://www.springframework.org/schema/tx
12         http://www.springframework.org/schema/tx/spring-tx.xsd
13         http://www.springframework.org/schema/context
14         http://www.springframework.org/schema/context/spring-context.xsd">
15         
16     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
17         <property name="driverClassName" value="${jdbc.driverClassName}"/>
18         <property name="url" value="${jdbc.url}"/>
19         <property name="username" value="${jdbc.username}"/>
20         <property name="password" value="${jdbc.password}"/>
21     </bean>
22     
23     <!-- jdbc事务管理器 -->
24     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
25         <property name="dataSource" ref="dataSource"></property>
26     </bean>
27     
28     <tx:annotation-driven transaction-manager="transactionManager"/>
29      
30     <context:property-placeholder location="jdbc.properties"/>
31     
32     <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
33         <constructor-arg ref="dataSource"></constructor-arg>
34     </bean>
35     
36     
37     <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
38         <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
39     </bean> 
40     
41     <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
42         <property name="bankDao" ref="bankDao"></property>
43     </bean> 
44     
45 </beans>

jdbc.properties:

1 jdbc.driverClassName=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
3 jdbc.username=root
4 jdbc.password=123456

BankServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 
 4 import org.springframework.transaction.annotation.Transactional;
 5 
 6 import com.wishwzp.dao.BankDao;
 7 import com.wishwzp.service.BankService;
 8 
 9 @Transactional
10 public class BankServiceImpl implements BankService{
11 
12     private BankDao bankDao;
13     
14     public void setBankDao(BankDao bankDao) {
15         this.bankDao = bankDao;
16     }
17     
18 
19     @Override
20     public void transferAccounts(int count, int userIdA, int userIdB) {
21         // TODO Auto-generated method stub
22                 // TODO Auto-generated method stub
23         bankDao.outMoney(count, userIdA);
24         bankDao.inMoney(count, userIdB);                
25     }
26 
27 }

BankService.java:

 1 package com.wishwzp.service;
 2 
 3 public interface BankService {
 4 
 5     /**
 6      * A向B转账count元
 7      * @param count
 8      * @param userIdA
 9      * @param userIdB
10      */
11     public void transferAccounts(int count,int userIdA,int userIdB);
12 }

BankDaoImpl.java:

 1 package com.wishwzp.dao.impl;
 2 
 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 5 
 6 import com.wishwzp.dao.BankDao;
 7 
 8 public class BankDaoImpl implements BankDao{
 9 
10     private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
11     
12     
13     public void setNamedParameterJdbcTemplate(
14             NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
15         this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
16     }
17     
18     @Override
19     public void inMoney(int money, int userId) {
20         // TODO Auto-generated method stub
21         String sql="update t_count2 set count=count+:money where userId=:userId";
22         MapSqlParameterSource sps=new MapSqlParameterSource();
23         sps.addValue("money", money);
24         sps.addValue("userId", userId);
25         namedParameterJdbcTemplate.update(sql,sps);
26     }
27 
28     @Override
29     public void outMoney(int money, int userId) {
30         // TODO Auto-generated method stub
31         String sql="update t_count set count=count-:money where userId=:userId";
32         MapSqlParameterSource sps=new MapSqlParameterSource();
33         sps.addValue("money", money);
34         sps.addValue("userId", userId);
35         namedParameterJdbcTemplate.update(sql,sps);
36     }
37 
38 }

BankDao.java:

1 package com.wishwzp.dao;
2 
3 public interface BankDao {
4 
5     public void inMoney(int money,int userId);
6     
7     public void outMoney(int money,int userId);
8 }

运行结果显示:

第四节:事务传播行为

事务传播行为:Spring 中,当一个service 方法调用另外一个service 方法的时候,因为每个service 方法都有事务,这时候就出现了事务的嵌套;由此,就产生了事务传播行为;

在Spring 中,通过配置Propagation,来定义事务传播行为;

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

 -------------------------------------------------------------------------------------------------------------------------------- 

<tx:attributes>

  <tx:method name="insert*" propagation="REQUIRED" />

  <tx:method name="update*" propagation="REQUIRED" />

  <tx:method name="edit*" propagation="REQUIRED" />

  <tx:method name="save*" propagation="REQUIRED" />

  <tx:method name="add*" propagation="REQUIRED" />

  <tx:method name="new*" propagation="REQUIRED" />

  <tx:method name="set*" propagation="REQUIRED" />

  <tx:method name="remove*" propagation="REQUIRED" />

  <tx:method name="delete*" propagation="REQUIRED" />

  <tx:method name="change*" propagation="REQUIRED" />

  <tx:method name="get*" propagation="REQUIRED" read-only="true" />

  <tx:method name="find*" propagation="REQUIRED" read-only="true" />

  <tx:method name="load*" propagation="REQUIRED" read-only="true" />

  <tx:method name="*" propagation="REQUIRED" read-only="true" />

</tx:attributes>

---------------------------------------------------------------------------------------------------------------------------- 

我们一般在项目中使用的是:使用XML 配置声明式事务。。。。。。。。。

为了增强性。。。其他不需要改变,只需要改一下beans.xml的配置文件

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans
 8         http://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/aop
10         http://www.springframework.org/schema/aop/spring-aop.xsd
11         http://www.springframework.org/schema/tx
12         http://www.springframework.org/schema/tx/spring-tx.xsd
13         http://www.springframework.org/schema/context
14         http://www.springframework.org/schema/context/spring-context.xsd">
15         
16     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
17         <property name="driverClassName" value="${jdbc.driverClassName}"/>
18         <property name="url" value="${jdbc.url}"/>
19         <property name="username" value="${jdbc.username}"/>
20         <property name="password" value="${jdbc.password}"/>
21     </bean>
22     
23     <!-- jdbc事务管理器 -->
24     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
25         <property name="dataSource" ref="dataSource"></property>
26     </bean>
27     
28     <!-- 配置事务通知 -->
29     <tx:advice id="txAdvice" transaction-manager="transactionManager">
30         <tx:attributes>  
31             <tx:method name="insert*" propagation="REQUIRED" />  
32             <tx:method name="update*" propagation="REQUIRED" />  
33             <tx:method name="edit*" propagation="REQUIRED" />  
34             <tx:method name="save*" propagation="REQUIRED" />  
35             <tx:method name="add*" propagation="REQUIRED" />  
36             <tx:method name="new*" propagation="REQUIRED" />  
37             <tx:method name="set*" propagation="REQUIRED" />  
38             <tx:method name="remove*" propagation="REQUIRED" />  
39             <tx:method name="delete*" propagation="REQUIRED" />  
40             <tx:method name="change*" propagation="REQUIRED" />  
41             <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
42             <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
43             <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
44             <tx:method name="*" propagation="REQUIRED" read-only="true" />  
45         </tx:attributes>  
46     </tx:advice>
47     
48     <!-- 配置事务切面 -->
49     <aop:config>
50         <!-- 配置切点 -->
51         <aop:pointcut id="serviceMethod" expression="execution(* com.wishwzp.service.*.*(..))" />
52         <!-- 配置事务通知 -->
53         <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
54     </aop:config>
55     
56  
57      
58     <context:property-placeholder location="jdbc.properties"/>
59     
60     <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
61         <constructor-arg ref="dataSource"></constructor-arg>
62     </bean>
63     
64     
65     <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
66         <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
67     </bean> 
68     
69     <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
70         <property name="bankDao" ref="bankDao"></property>
71     </bean> 
72     
73 </beans>
原文地址:https://www.cnblogs.com/wishwzp/p/5491637.html