Tôi có đoạn mã sau vào ả đào mùa xuân JdbcTemplate dựa -Làm thế nào để sử dụng cùng một kết nối cho hai truy vấn trong Spring?
getJdbcTemplate().update("Record Insert Query...");
int recordId = getJdbcTemplate().queryForInt("SELECT last_insert_id()");
Vấn đề là tôi thỉnh thoảng cập nhật của tôi và truy vấn queryForInt được thực hiện sử dụng các kết nối khác nhau từ hồ bơi kết nối.
Kết quả này trong một bản ghi không chính xácId được trả về vì MySql last_insert_id() được cho là được gọi từ cùng một kết nối đã đưa ra truy vấn chèn.
Tôi đã xem xét SingleConnectionDataSource nhưng không muốn sử dụng nó vì nó làm giảm hiệu suất của ứng dụng. Tôi chỉ muốn kết nối duy nhất cho hai truy vấn này. Không phải cho tất cả các yêu cầu cho tất cả các dịch vụ.
Vì vậy, tôi có hai câu hỏi:
- Tôi có thể quản lý các kết nối sử dụng bởi các lớp mẫu?
- JdbcTemplate có thực hiện quản lý giao dịch tự động không? Nếu tôi tự áp dụng một giao dịch cho phương thức Dao của tôi thì điều đó có nghĩa là hai giao dịch sẽ được tạo cho mỗi truy vấn?
Hy vọng rằng các bạn có thể làm sáng tỏ chủ đề.
Cập nhật - Tôi đã thử cách tiếp cận của nwinkler và gói lớp dịch vụ của tôi trong giao dịch. Tôi đã rất ngạc nhiên khi thấy cùng một lỗi xuất hiện trở lại sau một thời gian. Đào vào mã nguồn mùa xuân tôi thấy điều này -
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
throws DataAccessException {
//Lots of code
Connection con = DataSourceUtils.getConnection(getDataSource());
//Lots of code
}
Vì vậy, trái với những gì tôi nghĩ, không nhất thiết phải là một kết nối cơ sở dữ liệu cho mỗi giao dịch, nhưng một kết nối cho mỗi truy vấn thực hiện. Điều này đưa tôi trở lại vấn đề của tôi. Tôi muốn thực hiện hai truy vấn từ cùng một kết nối. :-(
Cập nhật -
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.jdbc.url}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.password}" />
<property name="maxActive" value="${db.max.active}" />
<property name="initialSize" value="20" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
autowire="byName">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception" timeout="30" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* service.*.*(..))" />
<aop:pointcut id="pointcut2" expression="execution(* *.ws.*.*(..))" />
<aop:advisor pointcut-ref="pointcut" advice-ref="transactionAdvice" />
<aop:advisor pointcut-ref="pointcut2" advice-ref="transactionAdvice" />
</aop:config>
Mh, sau đó tôi đoán bạn vẫn đang làm điều gì sai. Bạn có thể vui lòng đăng cấu hình Spring của mình, bao gồm cả quản lý dữ liệu và quản lý giao dịch không? Lớp nào là đoạn trích Spring từ đó? Bạn tìm thấy cái này ở đâu? – nwinkler
Mã đó là từ lớp JdbcTemplate. Nó được gọi là bất cứ khi nào một truy vấn được thực hiện, do đó tôi nghi ngờ. –
Hãy xem câu trả lời cập nhật của tôi ... – nwinkler