<!-- 引入属性文件 -->
<context:property-placeholder location="db.properties"/>
<!-- 创建数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 通过数据源配置JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务管理器,不管是用注解方式或xml方式配置事务,一定要有DataSourceTransactionManager事务管理器的支持 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="tx" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<!-- 在设置好的切入点表达式下再次进行事务设置 -->
<tx:method name="buyBook"/>
<tx:method name="checkOut"/>
<!-- 只有select开头的方法才会被事务处理 -->
<tx:method name="select*" read-only="true"/>
<tx:method name="insert*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 配置切入点表达式 -->
<aop:config>
<aop:pointcut expression="execution(* com.atguigu.book_xml.service.impl.*.*(..))" id="pointCut"/>
<aop:advisor advice-ref="tx" pointcut-ref="pointCut"/>
</aop:config>
</beans>
在xml里面定义了数据源bean,数据源bean又被事务管理器bean锁依赖,这时候用的数据源连接对象connection就是同一个,spring管理对象默认为单例
package com.atguigu.book.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.atguigu.book.service.BookService;
import com.atguigu.book.service.Cashier;
@Controller
public class BookController {
@Autowired
private BookService service;
@Autowired
private Cashier cashier;
public void buyBook() {
service.buyBook("1", "1001");
}
public void checkOut() {
List<String> bids = new ArrayList<>();
bids.add("1");
bids.add("2");
cashier.checkOut("1001", bids);
}
}
package com.atguigu.book.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.atguigu.book.service.BookService;
import com.atguigu.book.service.Cashier;
@Service
@Transactional
public class CashierServiceImpl implements Cashier {
@Autowired
private BookService service;
@Override
public void checkOut(String uid, List<String> bids) {
for (String bid : bids) {
service.buyBook(bid, uid);
}
}
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.5iyouxue.com /schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.oushengyuL.cn /schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.changjianyL.cn /schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.huangzuyuL.cn schema/tx/spring-tx-4.0.xsd">
<context:component-scan base-package="com.atguigu.book_xml"></context:component-scan>
System类包含一些有用的字段和方法,他不能被实例化
//用于垃圾回收
public static void gc()
//终止正在运行的java虚拟机。参数用作状态码,根据惯例,非0表示异常终止
public static void exit(int status)
//System.out.println(System.currentTimeMillis());
//返回从1970年1月1日到现在时间的毫秒数(协调时间)
public static currentTimeMills(www.chengsyl.cn)
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//src - 源数组。
//srcPos - 源数组中的起始位置。
//dest - 目标数组。
//destPos - 目的地数据中的起始位置。
//length - 要复制的数组元素的数量。
arraycopy方法的使用案例
int[] arr = {11, 22, 33, 44, 55};
int[] arr2 = {6, 7, 8, ,9 ,10};
System.arraycopy(arr, 1, arr2, 2, 2);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr2));
//运行结果
[11, 22, 33, 44, 55]
[6, 7, 22, 33, 10]
currentTimeMills()使用案例
package cn.bwh_www.jinLiyLd.cn2_currenTimeMillis;
public class SystemDemo {
public static void main(String[] args) {
//统计这段程序运行时间
long start = System.currentTimeMillis();
for (int x = 0; x www.chaoylgw.cn/< 10000; x++){
System.out.println("Hello" + x);
}
long end = System.currentTimeMillis();
System.out.println("共耗时" + (end - start) + "毫秒");
}
}
//运行结果
Hello9997
Hello9998
Hello9999
共耗时79毫秒
System.gc() 可用于垃圾回收.当使用System.gc() 回收某个对象所占用的内存之前,通过要求程序调用适当的方法来清理资源,在没有明确指定资源清理的情况下,Java提高了默认机制来清理该对象的资源,就是调用object类的finalize()方法,finalize()方法的作用是释放一个对象占用的内存空间时会被JVM调用.而子类重写该方法, 就可以清理对象占用的资源,该方法没有链式调用, 所以必须手动实现。
从程序结果上可以发现执行system.gc() 前系统会自动调用finalize() 方法清除对象占有的资源。通过super.finalize()可以实现从下到上的方法调用,即先释放自己的资源,再释放父类的资源。
但是不要在程序中频繁的调用垃圾回收,因为每一次执行垃圾回收jvm都会强制启动垃圾回收器运行,就会耗费更多的系统资源会与正常的Java程序运行争抢资源,只有在执行大量的对象的释放才调用垃圾回收最好。
package com.atguigu.book.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.atguigu.book.dao.BookDao;
import com.atguigu.book.exception.MyException;
import com.atguigu.book.service.BookService;
@Service
//@Transactional
public class BookServiceImpl implements BookService {
@Autowired
private BookDao dao;
/**
* @Transactional:对方法中所有的操作作为一个事务进行管理
* 在方法上使用,只对方法有效果
* 在类上使用,对类中所有的方法都有效果
* @Transactional中可以设置的属性:
*
* propagation:A方法和B方法都有事务,当A在调用B时,会将A中的事务传播给B方法,B方法对于事务的处理方式就是事务的传播行为
* Propagation.REQUIRED:必须使用调用者的事务
* Propagation.REQUIRES_NEW:将调用者的事务挂起,不使用调用者的事务,使用新的事务进行处理
*
* isolation:事务的隔离级别,在并发的情况下,操作数据的一种规定
* 读未提交:脏读 1
* 读已提交:不可重复读 2
* 可重复读:幻读 4
* 串行化:性能低,消耗大 8
*
*
* timeout:在事务强制回滚前最多可以执行(等待)的时间
*
* readOnly:指定当前事务中的一系列的操作是否为只读
* 若设置为只读,不管事务中有没有写的操作,mysql都会在请求访问数据的时候,不加锁,提高性能
* 但是如果有写操作的情况,建议一定不能设置只读
*
* rollbackFor|rollbackForClassName|noRollbackFor|noRollbackForClassName:设置事务回滚的条件
*/
@Transactional(propagation=Propagation.REQUIRES_NEW, timeout=3, noRollbackFor= {NullPointerException.class, MyException.class})
public void buyBook(String bid, String uid) {
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(www.feishenbo.cn);
}*/
Integer price = dao.selectPrice(bid);
dao.updateSt(bid);
dao.updateBalance(uid, price);
}
}
package com.atguigu.book.dao.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.atguigu.book.dao.BookDao;
import com.atguigu.book.exception.MyException;
@Repository
public class BookDaoImpl implements BookDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Integer selectPrice(String bid) {
Integer price = jdbcTemplate.queryForObject("select price from book where bid = ?", new Object[] {bid}, Integer.class);
return price;
}
@Override
public void updateSt(String bid) {
//获取该书籍的库存
Integer st = jdbcTemplate.queryForObject("select st from stock where sid = ?", new Object[] {bid}, Integer.class);
if(st <= 0) {
throw new RuntimeException();
}else {
jdbcTemplate.update("update stock set st = st -1 where sid = ?", bid);
}
}
@Override
public void updateBalance(String uid, Integer price) {
Integer balance = jdbcTemplate.queryForObject("select balance from money where uid = ?", new Object[] {uid}, Integer.class);
if(balance < price) {
throw new MyException("余额不足");
}else {
jdbcTemplate.update("update money set balance = balance - ? where uid = ?", price, uid);
为什么加个注解@Transtaional就可以保证事务的一致性和完整性?
猜你喜欢
转载自www.cnblogs.com/qwangxiao/p/11030133.html
今日推荐
周排行