青冈网站建设,国外教育网站模板,抄袭别人网站,建网站需要了解什么1 编写转账案例#xff0c;引出事务管理问题
需求#xff1a;账号转账#xff0c;Tom账号取出1000元#xff0c;存放到Jack账号上
1.1 建表脚本#xff08;MySQL#xff09; CREATE TABLE t_account (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) NOT NULL,m…1 编写转账案例引出事务管理问题
需求账号转账Tom账号取出1000元存放到Jack账号上
1.1 建表脚本MySQL CREATE TABLE t_account (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) NOT NULL,money DOUBLE DEFAULT NULL,PRIMARY KEY (id)
) INSERT INTO t_account (id, name, money) VALUES (1, tom, 1000);
INSERT INTO t_account (id, name, money) VALUES (2, jack, 1100);
INSERT INTO t_account (id, name, money) VALUES (3, rose, 2000); 1.2 新建工程
第一步新建一个maven项目 第二步引入依赖和applicationContext.xml配置文件和log4j.properties文件和db.properties文件
pom.xml: dependencies!-- junit测试 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.10/version/dependency!-- spring核心包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion4.2.8.RELEASE/version/dependency!-- spring集成测试 --dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion4.2.8.RELEASE/version/dependency!-- spring事物管理 --dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion4.2.8.RELEASE/version/dependency!-- c3p0数据源 --dependencygroupIdc3p0/groupIdartifactIdc3p0/artifactIdversion0.9.1.2/version/dependency!-- 数据库驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.6/version/dependency!-- 注解开发切面包 --dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.1/version/dependency/dependencies
applicationContext.xml:
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
/beans
log4j.properties:
### direct log messages to stdout ###
log4j.appender.stdoutorg.apache.log4j.ConsoleAppender
log4j.appender.stdout.TargetSystem.err
log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLoggerinfo, stdout
db.properties:
jdbc.driverClasscom.mysql.jdbc.Driver
jdbc.urljdbc:mysql://192.168.222.156:3306/spring?characterEncodingutf8useSSLfalse
jdbc.userroot
jdbc.password123456 第三步创建IAccountDao接口
创建AccounDaoImpl实现类实现了IAccountDao接口
账户操作持久层
技术方案jdbctempate
package com.example.demo.dao;public interface IAccountDao {// 转出public void out(String name, Double money);// 转入public void in(String name, Double money);
}第四步建立service层创建IAccountService接口编写转账的业务代码
package com.example.demo.service;public interface IAccountService {//转账业务:public void transfer(String outName,String inName,Double money);
}package com.example.demo.service.impl;import com.example.demo.dao.IAccountDao;
import com.example.demo.service.IAccountService;public class AccountServiceImpl implements IAccountService {// 注入daoprivate IAccountDao accountDao;public void setAccountDao(IAccountDao accountDao) {this.accountDao accountDao;}// 转账业务public void transfer(String outName, String inName, Double money) {// 先转出accountDao.out(outName, money);// 再转入accountDao.in(inName, money);}
}第五步: 将对象配置到spring工厂
applicationContext.xml文件添加配置 !-- 引入配置文件 --context:property-placeholder locationclasspath:db.properties /!-- 配置数据源 --bean iddataSource classcom.mchange.v2.c3p0.ComboPooledDataSourceproperty namedriverClass value${jdbc.driverClass} /property namejdbcUrl value${jdbc.url} /property nameuser value${jdbc.user} /property namepassword value${jdbc.password} //bean!-- 管理dao和service --bean idaccountDao classcom.example.demo.dao.impl.AccountDaoImpl!-- 注入数据源 --property namedataSource refdataSource //beanbean idaccountService classcom.example.demo.service.impl.AccountServiceImplproperty nameaccountDao refaccountDao/property/bean 第六步使用SpringTest进行测试
package com.example.demo.service.impl;import com.example.demo.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;//集成spring测试
RunWith(SpringJUnit4ClassRunner.class)
ContextConfiguration(locationsclasspath:applicationContext.xml)
public class AccountServiceImplTest {//注入测试对象Autowiredprivate IAccountService accountService;Testpublic void testTransfer() {accountService.transfer(tom, jack, 1000d);}}但是发现问题
事务管理问题在Service层没有事务的情况下如果出现异常则会转账不成功数据异常。
在转账方法中添加如下异常 运行前 运行后 事务未生效。
注意如果不配置事务那么每一个数据库的操作都是单独的一个事务。 2 XML配置方式添加事务管理(tx、aop元素)
【操作思路】aop三步走
确定目标需要对AccountService 的 transfer方法配置切入点需要Advice 环绕通知方法前开启事务方法后提交关闭事务配置切面和切入点
配置Advice通知
Spring为简化事务的配置提供了**tx:advice**来配置事务管理也可以理解为该标签是spring为你实现好了的事务的通知增强方案。 !-- 配置事物管理器 --bean idtransactionManagerclassorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource //bean!-- 配置事物通知 --!-- transaction-manager: 指定事物管理器的id,如果事物管理器的id为transactionManager的话 该属性可以省略(缺省值) --tx:advice idtxAdvice transaction-managertransactionManager!-- 配置事物管理细则(事物定义信息) --tx:attributes!-- 需要被增强(事物 管理)的方法 --tx:method nametransfer isolationDEFAULT propagationREQUIREDread-onlyfalse timeout-1 //tx:attributes/tx:advice!-- 配置切入点和切面 --aop:configaop:pointcut expressionbean(*Service) idmycut /aop:advisor advice-reftxAdvice pointcut-refmycut //aop:config 使用AccountServiceImplTest.java测试数据正常! 事物添加的前后对比
没有添加事务
两个方法分属不同事务。 添加事务后
分属同一事务 【注意】如果不配置则走默认的事务默认事务是每个数据库操作都是一个事务相当于没事务,所以我们开发时需要配置事务。 3 注解配置方式添加事务管理 Transactional
步骤
在需要管理事务的方法或者类上面 添加Transactional 注解配置注解驱动事务管理事务管理注解生效的作用需要配置对特定持久层框架使用的事务管理器
创建项目spring_transaction_anntx: 替换applicationContext.xml中的bean 配置为注解
改造dao:
package com.example.demo.dao.impl;import com.example.demo.dao.IAccountDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;import javax.sql.DataSource;Repository(accountDao)
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {//将数据源注入给父类,父类中需要通过数据源创建jdbctemplateAutowiredpublic void setSuperDataSource(DataSource dataSource){super.setDataSource(dataSource);}public void out(String name, Double money) {String sql update t_account set money money-? where name ?;super.getJdbcTemplate().update(sql, money, name);}public void in(String name, Double money) {String sql update t_account set money money? where name ?;super.getJdbcTemplate().update(sql, money, name);}
}改造service:
package com.example.demo.service.impl;import com.example.demo.dao.IAccountDao;
import com.example.demo.service.IAccountService;
import org.springframework.stereotype.Service;Service(accountService)
public class AccountServiceImpl implements IAccountService {// 注入daoAutowiredprivate IAccountDao accountDao;public void setAccountDao(IAccountDao accountDao) {this.accountDao accountDao;}// 转账业务public void transfer(String outName, String inName, Double money) {// 先转出accountDao.out(outName, money);// 再转入accountDao.in(inName, money);}
}在applicationContext.xml中配置注解扫描: !-- 开启注解扫描 --context:component-scan base-packagecom.example.demo /
测试方法是否能正常运行 以上步骤全部没问题后,开始配置注解方式的事物管理
第一步配置 事物管理器
在applicationContext.xml中,根据选用的持久层框架配置事物管理器: !-- 配置事物管理器 --bean idtransactionManagerclassorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource //bean
第二步: 在需要管理事物的方法上添加Transactional注解,表示对该方法进行事物管理 第三步在applicationContext.xml中开启事物注解驱动,让Transactional注解生效 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd!-- 引入配置文件 --context:property-placeholder locationclasspath:db.properties /!-- 配置数据源 --bean iddataSource classcom.mchange.v2.c3p0.ComboPooledDataSourceproperty namedriverClass value${jdbc.driverClass} /property namejdbcUrl value${jdbc.url} /property nameuser value${jdbc.user} /property namepassword value${jdbc.password} //bean!-- 开启注解扫描 --context:component-scan base-packagecom.example.demo /!-- 配置事物管理器 --bean idtransactionManagerclassorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource //bean!--配置事务注解驱动--tx:annotation-driven transaction-managertransactionManager //beans 第四步测试事物是否正常 提示:
如果 Transactional 标注在 Class 上面 那么将会对这个 Class 里面所有的 public 方法都包装事务方法。等同于该类的每个公有方法都放上了Transactional。
如果某方法需要单独的事务定义则需要在方法上加Transactional来覆盖类上的标注声明。记住方法级别的事务覆盖类级别的事务(就近原则)
package com.example.demo.service.impl;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import com.example.demo.dao.IAccountDao;
import com.example.demo.service.IAccountService;Service(accountService)
Transactional
// 放置在类上表示对该类中所有的方法都进行事物管理
public class AccountServiceImpl implements IAccountService {// 注入daoAutowiredprivate IAccountDao accountDao;// 转账业务Transactionalpublic void transfer(String outName, String inName, Double money) {// 先转出accountDao.out(outName, money);// 发生异常int i 1 / 0;// 再转入accountDao.in(inName, money);}Transactional(readOnly true)// 当方法上的事物定义信息和类上的冲突时,就近原则使用方法上的配置public Double queryMoney(String name) {// TODO Auto-generated method stubreturn null;}}
4 小结-xml和注解的选择
XML配置方式和注解配置方式进行事务管理 哪种用的多
XML方式集中式维护统一放置到applicationContext.xml文件中缺点在于配置文件中的内容太多。
使用Transactional注解进行事务管理配置太分散使用XML进行事务管理属性集中配置便于管理和维护
注意以后的service的方法名字的命名必须是上面规则否则不能被spring事务管理。
即以save开头的方法update开头的方法delete开头的方法表示增删改的操作故事务为可写
以find开头的方法表示查询故事务为只读 文章转载自: http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.qdsmile.cn.gov.cn.qdsmile.cn http://www.morning.ykrkq.cn.gov.cn.ykrkq.cn http://www.morning.dkslm.cn.gov.cn.dkslm.cn http://www.morning.qysnd.cn.gov.cn.qysnd.cn http://www.morning.cbtn.cn.gov.cn.cbtn.cn http://www.morning.drmbh.cn.gov.cn.drmbh.cn http://www.morning.plnry.cn.gov.cn.plnry.cn http://www.morning.qkkmd.cn.gov.cn.qkkmd.cn http://www.morning.tqqfj.cn.gov.cn.tqqfj.cn http://www.morning.fhxrb.cn.gov.cn.fhxrb.cn http://www.morning.dtrz.cn.gov.cn.dtrz.cn http://www.morning.pzrpz.cn.gov.cn.pzrpz.cn http://www.morning.bnmfq.cn.gov.cn.bnmfq.cn http://www.morning.xwbwm.cn.gov.cn.xwbwm.cn http://www.morning.gbjxj.cn.gov.cn.gbjxj.cn http://www.morning.tgczj.cn.gov.cn.tgczj.cn http://www.morning.rjqtq.cn.gov.cn.rjqtq.cn http://www.morning.pgzgy.cn.gov.cn.pgzgy.cn http://www.morning.qmbgb.cn.gov.cn.qmbgb.cn http://www.morning.ngmjn.cn.gov.cn.ngmjn.cn http://www.morning.tckxl.cn.gov.cn.tckxl.cn http://www.morning.tlrxt.cn.gov.cn.tlrxt.cn http://www.morning.qrpx.cn.gov.cn.qrpx.cn http://www.morning.flpjy.cn.gov.cn.flpjy.cn http://www.morning.sfdsn.cn.gov.cn.sfdsn.cn http://www.morning.pghfy.cn.gov.cn.pghfy.cn http://www.morning.lpbrp.cn.gov.cn.lpbrp.cn http://www.morning.gfqj.cn.gov.cn.gfqj.cn http://www.morning.trwkz.cn.gov.cn.trwkz.cn http://www.morning.zknjy.cn.gov.cn.zknjy.cn http://www.morning.lmrjn.cn.gov.cn.lmrjn.cn http://www.morning.qfwfj.cn.gov.cn.qfwfj.cn http://www.morning.xkjrq.cn.gov.cn.xkjrq.cn http://www.morning.rfhwc.cn.gov.cn.rfhwc.cn http://www.morning.jrsgs.cn.gov.cn.jrsgs.cn http://www.morning.xznrk.cn.gov.cn.xznrk.cn http://www.morning.mmtjk.cn.gov.cn.mmtjk.cn http://www.morning.rmlz.cn.gov.cn.rmlz.cn http://www.morning.hqrr.cn.gov.cn.hqrr.cn http://www.morning.mzmqg.cn.gov.cn.mzmqg.cn http://www.morning.qqbw.cn.gov.cn.qqbw.cn http://www.morning.tfwr.cn.gov.cn.tfwr.cn http://www.morning.rhfbl.cn.gov.cn.rhfbl.cn http://www.morning.kdnrc.cn.gov.cn.kdnrc.cn http://www.morning.jkszt.cn.gov.cn.jkszt.cn http://www.morning.zpqlf.cn.gov.cn.zpqlf.cn http://www.morning.wkmpx.cn.gov.cn.wkmpx.cn http://www.morning.gfrtg.com.gov.cn.gfrtg.com http://www.morning.wzknt.cn.gov.cn.wzknt.cn http://www.morning.smszt.com.gov.cn.smszt.com http://www.morning.qkdjq.cn.gov.cn.qkdjq.cn http://www.morning.wmyqw.com.gov.cn.wmyqw.com http://www.morning.cfnht.cn.gov.cn.cfnht.cn http://www.morning.fxygn.cn.gov.cn.fxygn.cn http://www.morning.mnnxt.cn.gov.cn.mnnxt.cn http://www.morning.kztts.cn.gov.cn.kztts.cn http://www.morning.stlgg.cn.gov.cn.stlgg.cn http://www.morning.nzms.cn.gov.cn.nzms.cn http://www.morning.gtxrw.cn.gov.cn.gtxrw.cn http://www.morning.fnmgr.cn.gov.cn.fnmgr.cn http://www.morning.hrjrt.cn.gov.cn.hrjrt.cn http://www.morning.ktrh.cn.gov.cn.ktrh.cn http://www.morning.zmpqh.cn.gov.cn.zmpqh.cn http://www.morning.qgxnw.cn.gov.cn.qgxnw.cn http://www.morning.rzrbw.cn.gov.cn.rzrbw.cn http://www.morning.qwdlj.cn.gov.cn.qwdlj.cn http://www.morning.rongxiaoman.com.gov.cn.rongxiaoman.com http://www.morning.mlhfr.cn.gov.cn.mlhfr.cn http://www.morning.mwqbp.cn.gov.cn.mwqbp.cn http://www.morning.nmrtb.cn.gov.cn.nmrtb.cn http://www.morning.rbnp.cn.gov.cn.rbnp.cn http://www.morning.ldqrd.cn.gov.cn.ldqrd.cn http://www.morning.wypyl.cn.gov.cn.wypyl.cn http://www.morning.fdwlg.cn.gov.cn.fdwlg.cn http://www.morning.lzjxn.cn.gov.cn.lzjxn.cn http://www.morning.whclz.cn.gov.cn.whclz.cn http://www.morning.zypnt.cn.gov.cn.zypnt.cn http://www.morning.fchkc.cn.gov.cn.fchkc.cn http://www.morning.slzkq.cn.gov.cn.slzkq.cn