• (五)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>
  • 相关阅读:
    在Docker中启动Nacos-Server
    maven配置阿里云公共仓库
    Centos7动态IP改静态后SSH很慢
    Vue+NodeJS的跨域请求Session不同
    一款非常简洁漂亮方便调用的jQuery前端分页
    springmvc后台接收List参数的几种办法
    net use命令详解(转)
    c#开发windows服务
    c# base64转字符串
    关于web api 验证
  • 原文地址:https://www.cnblogs.com/wishwzp/p/5491637.html
Copyright © 2020-2023  润新知