Spring实战之使用TransactionProxyFactoryBean实现声明式事务操作示例
本文实例讲述了spring实战之使用transactionproxyfactorybean实现声明式事务操作。分享给大家供大家参考,具体如下:
一 配置文件
<?xml version="1.0" encoding="gbk"?> <beans xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- 定义数据源bean,使用c3p0数据源实现,并注入数据源的必要信息 --> <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasource" destroy-method="close" p:driverclass="com.mysql.jdbc.driver" p:jdbcurl="jdbc:mysql://localhost/spring" p:user="root" p:password="32147" p:maxpoolsize="40" p:minpoolsize="2" p:initialpoolsize="2" p:maxidletime="30"/> <!-- 配置jdbc数据源的局部事务管理器,使用datasourcetransactionmanager 类 --> <!-- 该类实现platformtransactionmanager接口,是针对采用数据源连接的特定实现--> <!-- 配置datasourcetransactionmanager时需要依注入datasource的引用 --> <bean id="transactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager" p:datasource-ref="datasource"/> <!-- 配置一个业务逻辑bean --> <bean id="newsdao" class="org.crazyit.app.dao.impl.newsdaoimpl" p:ds-ref="datasource"/> <!-- 为业务逻辑bean配置事务代理 transactionmanager用于为配置事务代理注入所需的事务管理器 target用于指定为哪个bean配置事务代理 --> <bean id="newsdaotrans" class= "org.springframework.transaction.interceptor.transactionproxyfactorybean" p:transactionmanager-ref="transactionmanager" p:target-ref="newsdao"> <!-- 指定事务属性 --> <property name="transactionattributes"> <props> <prop key="*">propagation_required</prop> </props> </property> </bean> </beans>
二 dao
1 接口
package org.crazyit.app.dao; public interface newsdao { public void insert(string title, string content); }
2 实现类
package org.crazyit.app.dao.impl; import javax.sql.datasource; import java.sql.connection; import org.springframework.jdbc.core.jdbctemplate; import org.crazyit.app.dao.*; public class newsdaoimpl implements newsdao { private datasource ds; public void setds(datasource ds) { this.ds = ds; } public void insert(string title, string content) { jdbctemplate jt = new jdbctemplate(ds); jt.update("insert into news_inf" + " values(null , ? , ?)" , title , content); // 两次插入的数据违反唯一键约束 jt.update("insert into news_inf" + " values(null , ? , ?)" , title , content); // 如果没有事务控制,则第一条记录可以被插入 // 如果增加事务控制,将发现第一条记录也插不进去。 } }
三 测试类
package lee; import org.springframework.context.support.*; import org.springframework.context.*; import org.crazyit.app.dao.*; public class springtest { public static void main(string[] args) { // 创建spring容器 applicationcontext ctx = new classpathxmlapplicationcontext("beans.xml"); // 获取事务代理bean newsdao dao = (newsdao)ctx .getbean("newsdaotrans" , newsdao.class); // 执行插入操作 dao.insert("疯狂java" , "轻量级java ee企业应用实战"); } }
四 测试
数据库中无数据,说明事务生效。
exception in thread "main" org.springframework.dao.duplicatekeyexception: preparedstatementcallback; sql [insert into news_inf values(null , ? , ?)]; duplicate entry '疯狂java' for key 'news_title'; nested exception is com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry '疯狂java' for key 'news_title'
at org.springframework.jdbc.support.sqlerrorcodesqlexceptiontranslator.dotranslate(sqlerrorcodesqlexceptiontranslator.java:239)
at org.springframework.jdbc.support.abstractfallbacksqlexceptiontranslator.translate(abstractfallbacksqlexceptiontranslator.java:73)
at org.springframework.jdbc.core.jdbctemplate.execute(jdbctemplate.java:660)
at org.springframework.jdbc.core.jdbctemplate.update(jdbctemplate.java:909)
at org.springframework.jdbc.core.jdbctemplate.update(jdbctemplate.java:970)
at org.springframework.jdbc.core.jdbctemplate.update(jdbctemplate.java:980)
at org.crazyit.app.dao.impl.newsdaoimpl.insert(newsdaoimpl.java:33)
at sun.reflect.nativemethodaccessorimpl.invoke0(native method)
at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)
at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)
at java.lang.reflect.method.invoke(method.java:498)
at org.springframework.aop.support.aoputils.invokejoinpointusingreflection(aoputils.java:317)
at org.springframework.aop.framework.reflectivemethodinvocation.invokejoinpoint(reflectivemethodinvocation.java:190)
at org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:157)
at org.springframework.transaction.interceptor.transactioninterceptor$1.proceedwithinvocation(transactioninterceptor.java:98)
at org.springframework.transaction.interceptor.transactionaspectsupport.invokewithintransaction(transactionaspectsupport.java:262)
at org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:95)
at org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)
at org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:207)
at com.sun.proxy.$proxy4.insert(unknown source)
at lee.springtest.main(springtest.java:28)
caused by: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityconstraintviolationexception: duplicate entry '疯狂java' for key 'news_title'
at sun.reflect.nativeconstructoraccessorimpl.newinstance0(native method)
at sun.reflect.nativeconstructoraccessorimpl.newinstance(nativeconstructoraccessorimpl.java:62)
at sun.reflect.delegatingconstructoraccessorimpl.newinstance(delegatingconstructoraccessorimpl.java:45)
at java.lang.reflect.constructor.newinstance(constructor.java:423)
at com.mysql.jdbc.util.handlenewinstance(util.java:409)
at com.mysql.jdbc.util.getinstance(util.java:384)
at com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:1039)
at com.mysql.jdbc.mysqlio.checkerrorpacket(mysqlio.java:4232)
at com.mysql.jdbc.mysqlio.checkerrorpacket(mysqlio.java:4164)
at com.mysql.jdbc.mysqlio.sendcommand(mysqlio.java:2615)
at com.mysql.jdbc.mysqlio.sqlquerydirect(mysqlio.java:2776)
at com.mysql.jdbc.connectionimpl.execsql(connectionimpl.java:2838)
at com.mysql.jdbc.preparedstatement.executeinternal(preparedstatement.java:2082)
at com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2334)
at com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2262)
at com.mysql.jdbc.preparedstatement.executeupdate(preparedstatement.java:2246)
at com.mchange.v2.c3p0.impl.newproxypreparedstatement.executeupdate(newproxypreparedstatement.java:147)
at org.springframework.jdbc.core.jdbctemplate$2.doinpreparedstatement(jdbctemplate.java:916)
at org.springframework.jdbc.core.jdbctemplate$2.doinpreparedstatement(jdbctemplate.java:909)
at org.springframework.jdbc.core.jdbctemplate.execute(jdbctemplate.java:644)
... 18 more
下一篇: 详解基于MVC的数据查询模块进行模糊查询