ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring---事务管理练习 (maven)

2020-12-18 20:32:15  阅读:199  来源: 互联网

标签:maven www Spring commons springframework --- mybatis org public


案例:

  甲乙两个人转钱,正常情况下:甲输入乙的账号,输入金额,然后甲的账户扣除相应的钱,乙的账户扣除相应的钱;
但是就是有特殊情况,甲在输入账号的时候输错了,就会发生一个情况,甲的钱扣掉了,但是乙没有收到钱,肯定就会出现问题;这就是事务相关的问题:

解决办法:

  双方进行转账时其中一方发生异常,及时进行回滚,等待数据正常时在进行提交

 

一、创建进行转账的账号数据库

CREATE TABLE userinfo (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) DEFAULT NULL,
birthday datetime DEFAULT NULL,
sex varchar(1) DEFAULT NULL,
address varchar(255) DEFAULT NULL,
money int(255) DEFAULT NULL,
PRIMARY KEY (id) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

插入数据

INSERT INTO userinfo VALUES (1, ‘旺财’, ‘2020-09-29 00:00:00’, ‘女’, ‘五一广场’, 2100);
INSERT INTO userinfo VALUES (2, ‘来福’, ‘2020-09-16 00:00:00’, ‘男’, ‘五一新干线’, 700);
COMMIT;
主键:SET FOREIGN_KEY_CHECKS = 1;

二、导入相关包

 

<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>

<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.2.3</version>
<classifier>jdk15</classifier><!-- 指定jdk版本 -->
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.3</version>
</dependency>




</dependencies>
 
   

三、创建一个转账的接口

public interface Changmoney {

boolean giveMoney(int on,int to,int moeny);

}
 
   


四、xml配置

  一.SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<settings>
<!--<setting name="lazyLoadingEnabled" value="true"/>-->
<!--<setting name="aggressiveLazyLoading" value="false"/>-->
<!-- 开启二级缓存总开关 -->
<setting name="cacheEnabled" value="true"/>
<setting name="defaultStatementTimeout" value="25"/>
</settings>
<typeAliases>
<package name="cc.entity"/>
</typeAliases>

<!-- 配置mybatis的环境信息 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,采用dbcp连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.244.35:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<!-- 加载mapper -->
<mappers>
<!--<mapper resource="sqlmap/User.xml"/>-->
<package name="cc.mapper"/>
</mappers>

</configuration>

  二.创建generator.xml,用mybatis-generator自动生成器数据库简单语句、接口、实现类等

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/t142" userId="root"
password="123456">
</jdbcConnection>
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
userId="yycg"
password="yycg">
</jdbcConnection> -->

<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>

<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="pojo"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="cc.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="cc.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!--指定数据库表-->
<table tableName="userinfo"
domainObjectName="Userinfo"
enableCountByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
enableUpdateByExample="false"></table>


<!--<table tableName="test" domainObjectName="Test" enableCountByExample="false" enableDeleteByExample="false"-->
<!--enableSelectByExample="false" enableUpdateByExample="false"></table>-->

</context>
</generatorConfiguration>
 
   

  三.用测试类来生成接口和实现类(记得修改包的相关路径)

public static void main(String[] args)  throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("D:\\IDe\\Springzhuangz\\src\\config\\generator.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
 
   

  四.创建实现类

public class ChangeMoneyImpl implements Changmoney {


@Override
public boolean giveMoney(int on, int to, int moeny) {

SqlSession sqlSession = SqlSessionUtil.openSession();

UserinfoMapper mapper = sqlSession.getMapper(UserinfoMapper.class);

//转钱人信息
Userinfo userinfo = mapper.selectByPrimaryKey(on);
int i=0;

if (userinfo!=null){

//设置转钱人的余额
userinfo.setMoney(userinfo.getMoney()-moeny);

i = mapper.updateByPrimaryKey(userinfo);

}

//设置被转钱的信息
Userinfo userinfo1 = mapper.selectByPrimaryKey(to);
int j=0;

if (userinfo1!=null){

//设置被转钱人的余额
userinfo1.setMoney(userinfo1.getMoney()+moeny);

//受影响的行数
j = mapper.updateByPrimaryKey(userinfo1);
}


if (i>0&&j>0){
System.out.println("转钱成功");
//sqlSession.commit();
return true;
}else {
System.out.println("转钱失败");
//sqlSession.rollback();
return false;
}

}

}
 
   

  五.创建SqlSessionFactory工厂

public class SqlSessionUtil {
private static SqlSession sqlSession= null;
static {
//1、根据mybaits的配置文件构建SqlSessionFactory
//需要改成我们自己的SqlMapConfig.xml的路径
String resource = "SqlMapConfig.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、创建SqlSession
sqlSession= sqlSessionFactory.openSession();
}
public static SqlSession openSession() {
return sqlSession;
}

public static void main(String[] args) {
System.out.println(SqlSessionUtil.openSession());
}
}
 
   

  六.测试SqlSessionFactory

 

 

   测试类+结果

public class TestZhuangz {

public static void main(String[] args) {

Changmoney changmoney = new ChangeMoneyImpl();

boolean b = changmoney.giveMoney(1, 2, 200);
System.out.println(b);

}

}



 

 

 
   

  七.配置代理事务,配置数据库连接、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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">

<!--1、加载数据库的配置信息 -->
<context:property-placeholder location="database.properties"/>
<!--2、datasource数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}"/>
<property name="username" value="${username2}"/>
<property name="password" value="${password}"/>
</bean>
<!-- 3、sqlSessionFactory -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 别名 -->
<property name="typeAliasesPackage" value="com.cc.model"></property>
<!-- mapper XML映射 -->
<property name="mapperLocations" value="classpath*:mapper/*Mapper.xml"></property>
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.cc.mapper"></property>
</bean>

<!-- 5、事务管理 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

</beans>

 

 

 

<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 1、启动注解扫描-->
<context:annotation-config/>
<context:component-scan base-package="cc"></context:component-scan>


<!-- 1)目标 -->
<bean id="target" class="cc.change.ChangeMoneyImpl"></bean>
<!-- 2)黑客 -->
<bean id="transactionManager" class="cc.proxy.TransactionManager"></bean>
<!--3)代理 -->

<bean id="ChangeMoneyImpProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="cc.change.Changmoney"></property>
<!-- 1)注入目标对象 -->
<property name="target" ref="target"/>
<!-- 2)黑客对象 -->
<property name="interceptorNames">
<array>
<value>transactionManager</value>
</array>
</property>
</bean>

</beans>
 
   

  八.编写实体代理类

public class TransactionManager  implements MethodInterceptor{

@Override
public Object invoke(MethodInvocation method) throws Throwable {

SqlSession sqlSession = SqlSessionUtil.openSession();
//调用目标方法
boolean result = (boolean) method.proceed();
if( method.getMethod().getName().equals("giveMoney")){
if(result) {
sqlSession.commit();
System.out.println("====提交事务===");
}else {
sqlSession.rollback();
System.out.println("====回滚事务===");
}
}
return result;
}

}
 
   

  九.测试

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration({"classpath:beans.xml"})
public class Test2 {
@Autowired
@Qualifier("ChangeMoneyImplProxy")
changmoney changmoney;
@Test
public void test1(){
boolean b = changmoney.giveMoney(1, 2, 30);
System.out.println(b);
}
}

 
   

  实现

 

标签:maven,www,Spring,commons,springframework,---,mybatis,org,public
来源: https://www.cnblogs.com/1372841965ZQ/p/14156895.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有