(五)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:
package com.wishwzp.test; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wishwzp.service.BankService; public class T { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @Test
public void transferAccounts() {
BankService bankService=(BankService)ac.getBean("bankService");
//userId1向userId2转账了50元
bankService.transferAccounts(50, 1, 2);
} }
beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <context:property-placeholder location="jdbc.properties"/> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
BankServiceImpl.java:
package com.wishwzp.service.impl; import com.wishwzp.dao.BankDao;
import com.wishwzp.service.BankService; public class BankServiceImpl implements BankService{ private BankDao bankDao; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} @Override
public void transferAccounts(final int count, final int userIdA, final int userIdB) { bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
}
}
BankService.java:
package com.wishwzp.service; public interface BankService { /**
* A向B转账count元
* @param count
* @param userIdA
* @param userIdB
*/
public void transferAccounts(int count,int userIdA,int userIdB);
}
BankDaoImpl.java:
package com.wishwzp.dao.impl; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.wishwzp.dao.BankDao; public class BankDaoImpl implements BankDao{ private NamedParameterJdbcTemplate namedParameterJdbcTemplate; public void setNamedParameterJdbcTemplate(
NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
} @Override
public void inMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count set count=count+:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} @Override
public void outMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count set count=count-:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} }
BankDao.java:
package com.wishwzp.dao; public interface BankDao { public void inMoney(int money,int userId); public void outMoney(int money,int userId);
}
运行结果显示:
数据库中我们看到,我们的转账成功了。但是如果我们的程序中途出现了异常或者错误问题的话,那就不是这个样子的了。
例子:
将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:
package com.wishwzp.test; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wishwzp.service.BankService; public class T { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @Test
public void transferAccounts() {
BankService bankService=(BankService)ac.getBean("bankService");
//userId1向userId2转账了50元
bankService.transferAccounts(50, 1, 2);
} }
beans.xml:
package com.wishwzp.test; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wishwzp.service.BankService; public class T { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @Test
public void transferAccounts() {
BankService bankService=(BankService)ac.getBean("bankService");
//userId1向userId2转账了50元
bankService.transferAccounts(50, 1, 2);
} }
jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
BankServiceImpl.java:
package com.wishwzp.service.impl; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; import com.wishwzp.dao.BankDao;
import com.wishwzp.service.BankService; public class BankServiceImpl implements BankService{ private BankDao bankDao; private TransactionTemplate transactionTemplate; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
} @Override
public void transferAccounts(final int count, final int userIdA, final int userIdB) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// TODO Auto-generated method stub
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
}
});
}
}
BankService.java:
package com.wishwzp.service; public interface BankService { /**
* A向B转账count元
* @param count
* @param userIdA
* @param userIdB
*/
public void transferAccounts(int count,int userIdA,int userIdB);
}
BankDaoImpl.java:
package com.wishwzp.dao.impl; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.wishwzp.dao.BankDao; public class BankDaoImpl implements BankDao{ private NamedParameterJdbcTemplate namedParameterJdbcTemplate; public void setNamedParameterJdbcTemplate(
NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
} @Override
public void inMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count2 set count=count+:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} @Override
public void outMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count set count=count-:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} }
BankDao.java:
package com.wishwzp.dao; public interface BankDao { public void inMoney(int money,int userId); public void outMoney(int money,int userId);
}
运行结果显示:
这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了---------但是我们使用了编程式事务管理,这笔钱被事务滚回了。
虽然程序出现了问题,但是我们的赚钱也停止了,并没有任何损失。这就是使用事务的优点
但是编程式事务管理也有也大的缺点,就是编程式事务管理侵入到业务逻辑代码中了。这并不是我们想要的。。。。
所以我们一般使用的声明式事务管理。。。。。。。。。。。
第三节:声明式事务管理
声明式事务管理分两种:
1,使用XML 配置声明式事务;
2,使用注解配置声明式事务;
1,使用XML 配置声明式事务;
T.java:
package com.wishwzp.test; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wishwzp.service.BankService; public class T { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @Test
public void transferAccounts() {
BankService bankService=(BankService)ac.getBean("bankService");
bankService.transferAccounts(50, 1, 2);
} }
beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <!-- jdbc事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <!-- 配置事务切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="serviceMethod" expression="execution(* com.wishwzp.service.*.*(..))" />
<!-- 配置事务通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config> <context:property-placeholder location="jdbc.properties"/> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
BankServiceImpl.java:
package com.wishwzp.service.impl; import com.wishwzp.dao.BankDao;
import com.wishwzp.service.BankService; public class BankServiceImpl implements BankService{ private BankDao bankDao; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} @Override
public void transferAccounts(int count, int userIdA, int userIdB) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
} }
BankService.java:
package com.wishwzp.service; public interface BankService { /**
* A向B转账count元
* @param count
* @param userIdA
* @param userIdB
*/
public void transferAccounts(int count,int userIdA,int userIdB);
}
BankDaoImpl.java:
package com.wishwzp.dao.impl; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.wishwzp.dao.BankDao; public class BankDaoImpl implements BankDao{ private NamedParameterJdbcTemplate namedParameterJdbcTemplate; public void setNamedParameterJdbcTemplate(
NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
} @Override
public void inMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count2 set count=count+:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} @Override
public void outMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count set count=count-:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} }
BankDao.java:
package com.wishwzp.dao; public interface BankDao { public void inMoney(int money,int userId); public void outMoney(int money,int userId);
}
运行结果显示:
这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了---------但是我们使用了声明式事务管理,这笔钱被事务滚回了。
2,使用注解配置声明式事务;
T.java:
package com.wishwzp.test; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wishwzp.service.BankService; public class T { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @Test
public void transferAccounts() {
BankService bankService=(BankService)ac.getBean("bankService");
bankService.transferAccounts(50, 1, 2);
} }
beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <!-- jdbc事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <tx:annotation-driven transaction-manager="transactionManager"/> <context:property-placeholder location="jdbc.properties"/> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
BankServiceImpl.java:
package com.wishwzp.service.impl; import org.springframework.transaction.annotation.Transactional; import com.wishwzp.dao.BankDao;
import com.wishwzp.service.BankService; @Transactional
public class BankServiceImpl implements BankService{ private BankDao bankDao; public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
} @Override
public void transferAccounts(int count, int userIdA, int userIdB) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
} }
BankService.java:
package com.wishwzp.service; public interface BankService { /**
* A向B转账count元
* @param count
* @param userIdA
* @param userIdB
*/
public void transferAccounts(int count,int userIdA,int userIdB);
}
BankDaoImpl.java:
package com.wishwzp.dao.impl; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.wishwzp.dao.BankDao; public class BankDaoImpl implements BankDao{ private NamedParameterJdbcTemplate namedParameterJdbcTemplate; public void setNamedParameterJdbcTemplate(
NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
} @Override
public void inMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count2 set count=count+:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} @Override
public void outMoney(int money, int userId) {
// TODO Auto-generated method stub
String sql="update t_count set count=count-:money where userId=:userId";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("money", money);
sps.addValue("userId", userId);
namedParameterJdbcTemplate.update(sql,sps);
} }
BankDao.java:
package com.wishwzp.dao; public interface BankDao { public void inMoney(int money,int userId); public void outMoney(int money,int userId);
}
运行结果显示:
第四节:事务传播行为
事务传播行为: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:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <!-- jdbc事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<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>
</tx:advice> <!-- 配置事务切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="serviceMethod" expression="execution(* com.wishwzp.service.*.*(..))" />
<!-- 配置事务通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config> <context:property-placeholder location="jdbc.properties"/> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean> <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
</bean> <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl">
<property name="bankDao" ref="bankDao"></property>
</bean> </beans>
(五)Spring 对事务的支持的更多相关文章
- Spring(九)Spring对事务的支持
一.对事务的支持 事务:是一组原子操作的工作单元,要么全部成功,要么全部失败 Spring管理事务方式: JDBC编程事务管理:--可以控制到代码中的行 可以清楚的控制事务的边界,事务控制粒度化细(编 ...
- 峰Spring4学习(8)spring对事务的支持
一.事务简介: 二.编程式事务管理: 例子 1.需求:模拟转账,张三向李四转账50元: 数据库中存在t_count表: 代码实现: BankDao.java: package com.cy.dao; ...
- spring深入学习(五)-----spring dao、事务管理
访问数据库基本是所有java web项目必备的,不论是oracle.mysql,或者是nosql,肯定需要和数据库打交道.一开始学java的时候,肯定是以jdbc为基础,如下: private sta ...
- Spring框架事务支持模型的优势
全局事务 全局事务支持对多个事务性资源的操作,通常是关系型数据库和消息队列.应用服务器通过JTA管理全局性事务,API非常烦琐.UserTransaction通常需要从JNDI获取,意味着需要与JND ...
- 8.Spring对JDBC的支持和事务
1.Spring对JDBC的支持 DAO : Spring中对数据访问对象(DAO)的支持旨在简化Spring与数据访问技术的操作,使JDBC.Hibernate.JPA和JDO等采用统一的方式访问 ...
- 【Spring Framework】Spring入门教程(八)Spring的事务管理
事务是什么? 事务:指单个逻辑操作单元的集合. 在操作数据库时(增删改),如果同时操作多次数据,我们从业务希望,要么全部成功,要么全部失败.这种情况称为事务处理. 例如:A转账给B. 第一步,扣除A君 ...
- CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)
JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...
- 阶段3 2.Spring_10.Spring中事务控制_8 spring基于纯注解的声明式事务控制
新建项目 把之前项目src下的内容全部复制过来 pom.xml内复制过来 开始配置 新建一个config的包,然后再新建配置文件类SpringConfiguration @Configuration这 ...
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
转: http://blog.csdn.net/it_man/article/details/5074371 Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之 ...
随机推荐
- 【BZOJ4405】【WC2016】挑战NPC(带花树)
[BZOJ4405][WC2016]挑战NPC(带花树) 题面 BZOJ 洛谷 Uoj Description 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个 ...
- 解决:warning LNK4098: 默认库“MSVCRT”与其他库的使用冲突;找到 MSIL .netmodule 或使用 /GL 编译的模块;正在。。;LINK : warning LNK4075: 忽略“/INCREMENTAL”(由于“/LTCG”规范)
原文链接地址:https://www.cnblogs.com/qrlozte/p/4844411.html 参考资料: http://blog.csdn.net/laogaoav/article/de ...
- CF825F String Compression 解题报告
CF825F String Compression 题意 给定一个串s,其中重复出现的子串可以压缩成 "数字+重复的子串" 的形式,数字算长度. 只重复一次的串也要压. 求压缩后的 ...
- 第一个python教程(1)
使用文本编辑器 在Python的交互式命令行写程序,好处是一下就能得到结果,坏处是没法保存,下次还想运行的时候,还得再敲一遍. 所以,实际开发的时候,我们总是使用一个文本编辑器来写代码,写完了,保存为 ...
- Spring切面二使用注解
package com.IC; public interface PhoneBiz { public void buyPhone(int num); //购买手机; public void saleP ...
- hiho 1044 : 状态压缩
#1044 : 状态压缩·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车 ...
- .Net并行编程系列之一:并行基础
现在普通PC平台上面多核处理器的普及,让我们领教了能够利用多核进行并行计算的软件的处理能力,同时继承更多地核心正是当前处理器发展的趋势. 但是作为一个.NET开发人员,是否有时候会发现你的程序占用了其 ...
- [DeeplearningAI笔记]卷积神经网络1.2-1.3边缘检测
4.1卷积神经网络 觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.2边缘检测示例 边缘检测可以视为横向边缘检测和纵向边缘检测如下图所示: 边缘检测的原理是通过一个特定构造的卷积核对原始图 ...
- oracle的小语句
select * from v$nls_parameters; 查询数据库中现在的常量 alter session set NLS_DATE_FORMAT='yyyy-mm-dd'; 更改日期显示方式
- 分治法:快速排序求第K极值
标题其实就是nth_element函数的底层实现 nth_element(first, nth, last, compare) 求[first, last]这个区间中第n大小的元素 如果参数加入了co ...