1 package com.atlassian.sal.spring.connection;
2
3 import com.atlassian.sal.api.rdbms.ConnectionCallback;
4 import com.atlassian.sal.spi.HostConnectionAccessor;
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7 import org.springframework.transaction.PlatformTransactionManager;
8 import org.springframework.transaction.TransactionDefinition;
9 import org.springframework.transaction.TransactionStatus;
10 import org.springframework.transaction.support.DefaultTransactionDefinition;
11 import org.springframework.transaction.support.TransactionCallback;
12 import org.springframework.transaction.support.TransactionTemplate;
13
14 import java.sql.Connection;
15 import java.sql.SQLException;
16 import javax.annotation.Nonnull;
17
18
19
20
21
22
23
24
25
26
27 public class SpringHostConnectionAccessor implements HostConnectionAccessor
28 {
29 private static final Logger log = LoggerFactory.getLogger(SpringHostConnectionAccessor.class);
30
31 private final ConnectionProvider connectionProvider;
32
33 private final PlatformTransactionManager transactionManager;
34
35 public SpringHostConnectionAccessor(@Nonnull final ConnectionProvider connectionProvider, @Nonnull final PlatformTransactionManager transactionManager)
36 {
37 this.connectionProvider = connectionProvider;
38 this.transactionManager = transactionManager;
39 }
40
41 @Override
42 public <A> A execute(final boolean readOnly, final boolean newTransaction, @Nonnull final ConnectionCallback<A> callback)
43 {
44
45 final DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
46 transactionDefinition.setName("SALSpringTx");
47 transactionDefinition.setReadOnly(readOnly);
48 transactionDefinition.setPropagationBehavior(newTransaction ? TransactionDefinition.PROPAGATION_REQUIRES_NEW : TransactionDefinition.PROPAGATION_REQUIRED);
49
50
51 final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager, transactionDefinition);
52
53
54
55 return (A) transactionTemplate.execute(new TransactionCallback()
56 {
57 @Override
58 public Object doInTransaction(final TransactionStatus status)
59 {
60
61
62 final Connection connection = connectionProvider.getConnection();
63
64
65 final A result = callback.execute(connection);
66
67 try
68 {
69 connection.close();
70 }
71 catch (SQLException e)
72 {
73
74 log.error("unable to close java.sql.Connection", e);
75 }
76
77 return result;
78 }
79 });
80 }
81
82
83
84
85 public interface ConnectionProvider
86 {
87
88
89
90
91
92
93
94
95
96
97 @Nonnull
98 Connection getConnection();
99 }
100 }