Java主动让子线程回滚_spring事务回滚处理+多线程异步处理

spring事务回滚处理:

准备:配置好spring+mybatis环境。

一、XML方式配置spring事务处理

第一步: spring.xml配置:

第二步:编写测试代码:

TestController.java

package org.jun.controller;

import org.jun.controller.base.AbstractController;

import org.springframework.stereotype.Controller;

import org.springframework.transaction.interceptor.TransactionAspectSupport;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

/**

*

* @author xiejunbo

*

**/

@Controller

@RequestMapping("test")

public class TestController extends AbstractController {

@ResponseBody

@RequestMapping("trade")

public String trade(){

try {

testService.trade();

} catch (Exception e) {

logger.error("[error] trade error!" + e);

}

return "success";

}

}

==============================================================================

TestService.java

package org.jun.service;

/**

*

* @author xiejunbo

*

**/

public interface TestService {

void trade() throws Exception;

}

==========================================================================

TestServiceImpl.java

package org.jun.service;

import javax.annotation.Resource;

import org.jun.mapper.TestMapper;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

/**

*

* @author xiejunbo

*

**/

@Service

public class TestServiceImpl implements TestService {

@Resource

private TestMapper testMapper;

public void trade() throws Exception{

try {

testMapper.updateBalance();

int i = 10/0;

testMapper.record();

} catch (RuntimeException e) {

throw new Exception(e);

}

}

}

第三步:结果分析:

如果事务正常回滚,表中数据无变化。

如果事务没有回滚,表中对应记录的余额被更新,但没有新添加的记录

6f7abf4f41edbeb58b18546de08bfa68.png

第四步:如果事务无法回滚:

检查:确认有抛异常,确认扫描包的位置正确,确认没有重复扫描对应包。

通常只会在service层处理事务回滚操作.

一、注解方式配置spring事务处理

XML配置:

spring.xml:

springmvc.xml:

TestController.java:

package org.web.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.web.controller.base.AbstractController;

import org.web.domain.User;

@Controller

@RequestMapping("test")

public class TestController extends AbstractController{

@ResponseBody

@RequestMapping("trade")

public String trade() {

try {

User u = new User();

u.setId(1);

u.setUsername("xiejunbo");

u.setPwd("123456");

testService.trade(u);

} catch (Exception e) {

logger.error("[error]" + e);

}

return "success";

}

}

TestServiceImpl.java:

package org.web.service.impl;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import org.web.domain.User;

import org.web.mapper.TestMapper;

import org.web.service.TestService;

@Service

public class TestServiceImpl implements TestService {

@Autowired

private TestMapper testMapper;

@Transactional(rollbackFor=Exception.class)

public void trade(User u) throws Exception {

try {

testMapper.substract(u);

u.setId(2);

testMapper.add(u);

testMapper.record(u);

int i = 10/0;

} catch (Exception e) {

throw new Exception(e);

}

}

}

注意:扫描包时,对事务注解annotation只扫描一次,重复扫描会导致事务失效。

操作结果:

dcbd39bbe8f2d11a5626ae52f0947d27.png

多线程异步处理:

/***

用户注册接口

@RequestMapping("/register")

@ResponseBody

public Resp register(final User user, String verifyCode, HttpServletRequest request, HttpServletResponse response)

throws FileNotFoundException {

final String password = user.getPwd();

User result = null;

Map ageAndConstell = CommonHelper.getAgeAndConstell(user.getBirth());

try {

result = resource.createUser(user);

if (result != null) { // 异步注册

user.setId(result.getId());

threadPool.execute(new Runnable() {

@Override

public void run() {

String imid = CryptUtil.md5(user.getPhone());

String username = hx.register(imid, password, user.getNick());

if (StringUtils.isNotBlank(username)) { // 注册成功

user.setImid(imid);

redis.set(Consts.Cache.USER_PREFIX + user.getId(), user);

} else { //注册失败

log.error("register error imid:{}", imid);

}

}

});

}

} catch (Exception e) {

log.error("[/user/register] error ", e);

return error(e);

}

return result != null ? success(user, "注册成功") : fail(); // 将user返回

}

@Autowired

protected ThreadPool threadPool;

import java.util.concurrent.LinkedBlockingQueue;

import java.util.concurrent.ThreadFactory;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPool extends ThreadPoolExecutor {

private String poolName;

/**

* 创建线程数固定大小的线程池

*

* @param poolSize

* @param poolName 线程池的名称必须设置

*/

public ThreadPool(int poolSize, String poolName) {

super(poolSize, poolSize, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamingThreadFactory(

poolName));

this.poolName = poolName;

}

public String getPoolName() {

return poolName;

}

public void setPoolName(String poolName) {

this.poolName = poolName;

}

private static class NamingThreadFactory implements ThreadFactory {

private String threadName;

private AtomicInteger counter = new AtomicInteger(1);

public NamingThreadFactory(String threadName) {

this.threadName = threadName;

}

@Override

public Thread newThread(Runnable r) {

int index = counter.getAndIncrement();

return new Thread(r, threadName + "-" + index);

}

}

public String toString() {

String str = super.toString();

int idx = str.indexOf("[");

if (idx == -1) {

return "[name = " + poolName + "]";

}

String s = str.substring(idx + 1);

return "[name = " + poolName + ", " + s;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值