如何在SpringJdbc中使BeanPropertyRowMapper线程安全?

时间:2015-11-03 16:32:18

标签: java multithreading spring thread-safety spring-jdbc

我在我的应用程序中使用spring jdbctemplate,在我的查询中我使用行映射为新的BeanPropertyRowMapper(dto.class) 但是我从客户端获得评论,以使行映射线程安全。怎么做?

查询方法如下:

jdbcTemplate.query(qry, new Object[]("abc"), 
    new BeanPropertyRowMapper<dto>(dto.class))

2 个答案:

答案 0 :(得分:1)

鉴于从DAO实例方法调用此代码:

jdbcTemplate.query(qry, new Object[]("abc"), new BeanPropertyRowMapper<dto>(dto.class))

(其中jdbcTemplate是Spring注入的DAO的实例成员,DAO是具有单例范围的Spring管理的bean),这似乎没问题。 BeanPropertyRowMapper是有状态的,如果由多个线程同时使用,则不会是线程安全的,但是你不会将它暴露给多个线程,你以线程限制的方式使用它是安全的。

Java Concurrency in Practice ,第3.3节讨论了一般的线程限制:

  

访问共享的可变数据需要使用同步;避免这种要求的一种方法是不共享。如果仅从单个线程访问数据,则不需要同步。这种技术,线程限制,是实现线程安全的最简单方法之一。当一个对象被限制在一个线程中时,即使受限对象本身不是[CPJ 2.3.2],这种用法也是自动线程安全的。

它还讨论了(在3.3.2中)你正在做的特定类型的线程限制:

  

堆栈限制是线程限制的一种特殊情况,其中只能通过局部变量访问对象。就像封装可以更容易保存不变量一样,局部变量可以更容易将对象限制在线程中。局部变量本质上局限于执行线程;它们存在于执行线程的堆栈中,其他线程无法访问它。堆栈限制(也称为线程内或线程本地使用,但不要与ThreadLocal库类混淆)维护起来更简单,并且比ad-hoc线程限制更不易碎。

对RowMapper的唯一引用是在为该方法调用创建的堆栈框架上。没有其他线程(包括在同一个DAO上调用相同方法的线程)可以访问它。告诉你的客户这个对象已经安全了,因为只能通过局部变量访问,并且可以参考JCIP书中引用的段落,这是一个权威的参考书。

答案 1 :(得分:0)

您的代码已经是线程安全的。但您可以通过创建常量来提高其性能。 BeanPropertyRowMapper类具有可变数据。但是一旦初始化,这些数据就不会改变,因此类是线程安全的。

例:

private static final BeanPropertyRowMapper<dto> DTO_ROW_MAPPER = new dto<dto>(DtoDetailEvenement.class);
...
jdbcTemplate.query(qry, new Object[]("abc"), DTO_ROW_MAPPER)