- 浏览: 1248264 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (193)
- ant/maven (6)
- algorithm (5)
- tomcat/weblogic/jboss (6)
- javascript/jquery (13)
- java (33)
- flex/flash (0)
- JPA/Hibernate/myBatis (18)
- java concurrent (7)
- test (2)
- windows/linux (6)
- java collection (7)
- design pattern (2)
- life/health (3)
- database (12)
- IDE (4)
- spring/ejb (20)
- html/css/ckeditor (7)
- jsp/servlet (3)
- java io (13)
- java security (4)
- jni (0)
- svn/git (2)
- english (2)
- java jmx (1)
- xml (1)
- struts/springmvc (9)
- middleware (2)
- cache (1)
- cglib (3)
最新评论
-
jlotusYo:
博主,真感谢。
Java 密码扩展无限制权限策略文件 -
senninha:
这个。。是api说明吧。。
ScheduledExecutorService 源码分析 -
zoutao2008:
请问大文件如何处理?按你这种方式的话,文件超过200M时就会报 ...
hessian系列之二:上传文件 -
lwj1113:
lwj1113 写道谢谢博主这么细致的demo;在系列五中通过 ...
myBatis系列之五:与Spring3集成 -
lwj1113:
谢谢博主这么细致的demo;在系列五中通过testng测试类跑 ...
myBatis系列之五:与Spring3集成
本地事务即对一个数据源进行操作。大多数数据库支持事务。
先看没有事务的时候,导致的数据不一致问题。
准备数据:
Maven依赖:
接口:
实现类:
Spring配置文件:
测试:
用户user1的余额是20,买了3个单价为10的苹果,余额不够支付,报错。但是数据处于不一致状态:fruit_stock表的苹果存量由10个减为7个,而账户表的余额还是20,需要使用事务。
使用JDBC的事务操作。
上面的数据源是写在代码里的,每次修改都需要重新编译,可以将其放在Spring配置中:
先看没有事务的时候,导致的数据不一致问题。
准备数据:
-- MySQL -- Create the database DROP DATABASE IF EXISTS spring; CREATE DATABASE spring -- Drop three tables if exist DROP TABLE IF EXISTS FRUIT; DROP TABLE IF EXISTS FRUIT_STOCK; DROP TABLE IF EXISTS ACCOUNT; -- 水果表 CREATE TABLE FRUIT ( ID INT NOT NULL, FRUIT_NAME VARCHAR(100) NOT NULL, PRICE INT, PRIMARY KEY (ID) ); -- 水果存货表 CREATE TABLE FRUIT_STOCK ( ID INT NOT NULL, STOCK INT NOT NULL, PRIMARY KEY (ID), CHECK (STOCK >= 0) -- analyzed but ignored by MySQL ); -- 账户表 CREATE TABLE ACCOUNT ( USERNAME VARCHAR(50) NOT NULL, BALANCE INT NOT NULL, PRIMARY KEY (USERNAME), CHECK (BALANCE >= 0) ); -- Add initial data INSERT INTO FRUIT(ID, FRUIT_NAME, PRICE) VALUES(1, 'Apple', 10); INSERT INTO FRUIT_STOCK(ID, STOCK) VALUES(1, 10); INSERT INTO ACCOUNT(USERNAME, BALANCE) VALUES('user1', 20); DELIMITER $$ -- MySQL不支持check,使用触发器来检查约束,不满足时触发异常: CREATE TRIGGER ACCOUNT_BALANCEGT0 BEFORE UPDATE ON account FOR EACH ROW BEGIN IF NEW.balance < 0 THEN -- NEW代表更新后的记录 CALL xxx_yyy(); UPDATE _xxx_yyy SET X = 1; -- 引发异常 END IF; END$$ DELIMITER ;
Maven依赖:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.1.2.RELEASE</version> </dependency>
接口:
public interface FruitShop { // fruitId - 水果ID, userName - 用户号, count - 购买数量 boolean purchase(int fruitId, String userName, int count); }
实现类:
public class JdbcFruitShop implements FruitShop { static final Logger LOGGER = LoggerFactory.getLogger(JdbcFruitShop.class); @Override public boolean purchase(int fruitId, String userName, int count) { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); // Load the driver conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/spring?characterEncoding=utf8", "spring", "123456"); // Get the connection // Query the price PreparedStatement ps1 = conn.prepareStatement("SELECT PRICE FROM FRUIT WHERE ID = ?"); ps1.setInt(1, fruitId); ResultSet rs = ps1.executeQuery(); int price = 0; if (rs.next()) { price = rs.getInt(1); } ps1.close(); // Update the stock PreparedStatement ps2 = conn.prepareStatement("UPDATE FRUIT_STOCK SET STOCK = STOCK - ? WHERE ID = ?"); ps2.setInt(1, count); ps2.setInt(2, fruitId); ps2.executeUpdate(); ps2.close(); // Update the balance PreparedStatement ps3 = conn .prepareStatement("UPDATE ACCOUNT SET BALANCE = BALANCE - ? WHERE USERNAME = ?"); ps3.setInt(1, price * count); ps3.setString(2, userName); ps3.executeUpdate(); ps3.close(); } catch (SQLException e) { LOGGER.error("Purchase error:", e); } catch (ClassNotFoundException e) { LOGGER.error("driver Loading error:", e); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { LOGGER.error("Connection closing error:", e); } } } return true; } }
Spring配置文件:
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="fruitShop" class="com.john.tx.service.impl.JdbcTxFruitShop"/> </beans>
测试:
@Resource FruitShop fruitShop; @Test public void test() { int fruitId = 1; String userName = "user1"; int count = 3; fruitShop.purchase(fruitId, userName, count); }
用户user1的余额是20,买了3个单价为10的苹果,余额不够支付,报错。但是数据处于不一致状态:fruit_stock表的苹果存量由10个减为7个,而账户表的余额还是20,需要使用事务。
使用JDBC的事务操作。
public class JdbcTxFruitShop implements FruitShop { @Override public boolean purchase(int fruitId, String userName, int count) { ... conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/spring?characterEncoding=utf8", "spring", "123456"); // Get the connection conn.setAutoCommit(false); // 取消自动提交 ... ps3.close(); conn.commit(); // 提交事务 ... } }
上面的数据源是写在代码里的,每次修改都需要重新编译,可以将其放在Spring配置中:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/spring?characterEncoding=utf8" /> <property name="username" value="spring" /> <property name="password" value="123456" /> </bean> <bean id="fruitShop" class="com.john.tx.service.impl.JdbcTxFruitShop"> <property name="dataSource" ref="dataSource" /> </bean>
public class JdbcTxFruitShop implements FruitShop { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } @Override public boolean purchase(int fruitId, String userName, int count) { ... conn = dataSource.getConnection(); ... } }
发表评论
-
本地事务系列之五:使用Transactional注解
2014-08-02 18:16 2834AOP的配置稍显复杂,通过@Transactional注解,同 ... -
本地事务系列之四:使用AOP
2014-08-02 17:08 907Spring AOP通过在文件中配置来管理事务,好处是对代码侵 ... -
本地事务系列之三:使用TransactionTemplate
2014-07-17 22:15 6777TransactionTemplate的灵活性好,可以给代码块 ... -
本地事务系列之二:使用PlatformTransactionManager
2014-07-17 21:37 5404Spring的事务管理器接口: public interf ... -
Spring AOP 源码系列:ProxyFactoryBean
2014-04-21 18:01 0public class ProxyFactoryBean ... -
Spring AOP 源码系列
2014-04-21 09:22 0Spring AOP通过JDK的正则表达式对Pointcut表 ... -
Spring AOP系列之五:后置通知
2014-04-14 08:59 1677和前置通知类似, 通过实现org.springframewor ... -
Spring AOP系列之四:前置通知
2014-04-13 21:28 1834通过实现org.springframework.aop.M ... -
Spring AOP系列之三:环绕代理
2014-04-13 18:20 1425通过实现org.aopalliance.intercept.M ... -
Spring AOP系列之二:Java代理
2014-04-13 18:00 1053通过Java代理的方式: 汽车的代理,需要实现java.la ... -
Spring AOP系列之一:手动方式
2014-04-13 17:44 1394AOP (Aspect Oriented Progra ... -
HibernateTemplate 使用
2014-03-03 22:09 01. queryListBySql hibernateTe ... -
Spring的组件扫描
2017-09-16 21:58 1069Spring2.0以后的版本中,引入了基于注解(Annotat ... -
ContextLoaderListener和ContextCleanupListener源码分析
2013-12-18 15:55 0public class ContextLoaderLis ... -
Cglib2AopProxy 源码分析
2013-12-05 14:30 0final class Cglib2AopProxy im ... -
Spring生命周期方法的调用顺序
2013-11-19 22:04 0Spring的几个接口: BeanFactoryAware: ... -
一、Spring AOP的简单实例
2013-11-06 23:31 17821. 往pom.xml文件添加以下依赖: <depe ... -
Spring配置中的bean引用其它bean的属性值
2013-01-23 15:24 4236这项功能在spring的3.0版本以上才支持,如果使用较早的版 ... -
spring JPA struts 整合开发(2) - spring集成struts
2012-05-20 20:55 1436一. spring JPA struts 整合开发(1) - ... -
spring JPA struts 整合开发(1) - spring集成JPA
2012-05-20 20:26 1708一. spring JPA struts 整合开发(1) - ...
相关推荐
setting.xml文件,修改Maven仓库指向至阿里仓
基于java的玉安农副产品销售系统的开题报告
dev-c++ 6.3版本
基于java的项目监管系统开题报告
基于springboot多彩吉安红色旅游网站源码数据库文档.zip
毕业设计&课设_基于 AFLFast 改进能量分配策略的毕业设计项目,含 Mix Schedule策略设计及测试结果分析.zip
基于springboot办公用品管理系统源码数据库文档.zip
C++调用qml对象Demo
非常漂亮的类Web界面的Delphi设计54ed7-main.zip
VB SQL车辆管理系统是一款基于Visual Basic(VB)编程语言和SQL数据库开发的综合车辆管理工具。该系统集成了车辆信息管理、驾驶员信息管理、车辆调度、维修记录、数据存储与检索、报告生成以及安全权限管理等多个核心功能模块。 源代码部分提供了详细的开发流程和实现方法,涵盖了从数据库设计、界面设计到事件驱动编程、数据访问技术和错误处理等关键技术点。通过该系统,用户可以方便地录入、查询、修改和删除车辆及驾驶员信息,实现车辆信息的实时更新和跟踪。同时,系统还支持生成各类车辆管理相关的报告,帮助用户更好地掌握车辆运营情况。 系统部分则采用了直观易用的用户界面设计,使得用户能够轻松上手并快速完成车辆管理工作。系统还具备强大的数据处理能力和安全性,通过数据备份和系统升级优化等功能,确保数据的完整性和系统的稳定运行。 总体而言,VB SQL车辆管理系统是一款功能全面、易于操作且安全可靠的车辆管理工具,适用于企业和个人进行日常车辆运营和管理。无论是车辆信息的录入、查询还是报告生成,该系统都能够提供高效、便捷的服务,是车辆管理工作的理想选择。
AutoSAR基础学习资源
基于springboot英语学习平台源码数据库文档.zip
数据集,深度学习,密封数据集,马体态数据集
基于java的数字家庭网站开题报告
podman使用国内源镜像加速器
基于springboot+web的留守儿童网站源码数据库文档.zip
基于springboot的智能宾馆预定系统源码数据库文档.zip
GetQzonehistory-main.zip
环境说明:开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat 开发软件:eclipse/myeclipse/idea Maven包:Maven 浏览器:谷歌浏览器。 项目经过测试均可完美运行
内容概要:本文档详细介绍了QST公司生产的QMI8A01型号的6轴惯性测量单元的数据表及性能参数。主要内容包括设备特性、操作模式、接口标准(SPI、I2C与I3C),以及各种运动检测原理和技术规格。文中还提到了设备的工作温度范围宽广,内置的大容量FIFO可用于缓冲传感器数据,减少系统功耗。此外,对于器件的安装焊接指导亦有详细介绍。 适合人群:电子工程技术人员、嵌入式开发人员、硬件设计师等。 使用场景及目标:适用于需要精准测量物体空间位置变化的应用场合,如消费电子产品、智能穿戴设备、工业自动化等领域。帮助工程师快速掌握该款IMU的技术要点和应用场景。 其他说明:文档提供了详细的电气连接图表、封装尺寸图解等资料,方便用户进行电路板的设计制作。同时针对特定应用提出了一些优化建议。