summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/db/MysqlConnection.java
blob: d9fe4f2a061c4547b23cd179605f5cc81778ba37 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package org.openslx.imagemaster.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MysqlConnection implements AutoCloseable
{

	private static final Logger LOGGER = LogManager.getLogger( MysqlConnection.class );

	private static final int CONNECTION_TIMEOUT_MS = 5 * 60 * 1000;

	private final long deadline = System.currentTimeMillis() + CONNECTION_TIMEOUT_MS;

	private final Connection rawConnection;

	private boolean hasPendingQueries = false;

	private List<MysqlStatement> openStatements = new ArrayList<>();

	MysqlConnection( Connection rawConnection )
	{
		this.rawConnection = rawConnection;
	}

	public MysqlStatement prepareStatement( String sql ) throws SQLException
	{
		if ( !sql.startsWith( "SELECT" ) && !sql.startsWith( "DESCRIBE" ) && !sql.startsWith( "SHOW" ) ) {
			hasPendingQueries = true;
		}
		MysqlStatement statement = new MysqlStatement( rawConnection, sql );
		openStatements.add( statement );
		return statement;
	}

	public void commit() throws SQLException
	{
		rawConnection.commit();
		hasPendingQueries = false;
	}

	public void rollback() throws SQLException
	{
		rawConnection.rollback();
		hasPendingQueries = false;
	}

	boolean isValid()
	{
		return System.currentTimeMillis() < deadline;
	}

	@Override
	public void close()
	{
		if ( hasPendingQueries ) {
			LOGGER.warn( "Mysql connection had uncommited queries on .close()",
					new RuntimeException( "Stack trace" ) );
			for ( MysqlStatement s : openStatements ) {
				LOGGER.info( s.getQuery() );
			}
			hasPendingQueries = false;
		}
		try {
			rawConnection.rollback();
		} catch ( SQLException e ) {
			LOGGER.warn( "Rolling back uncommited queries failed!", e );
		}
		if ( !openStatements.isEmpty() ) {
			for ( MysqlStatement statement : openStatements ) {
				statement.close();
			}
			openStatements.clear();
		}
		try {
			rawConnection.rollback();
			rawConnection.setAutoCommit( true );
		} catch ( SQLException e ) {
			LOGGER.warn( "Rolling back uncommited queries failed!", e );
		}
		Database.returnConnection( this );
	}

	void release()
	{
		try {
			rawConnection.close();
		} catch ( SQLException e ) {
			// Nothing meaningful to do
		}
	}

	void setAutoCommit( boolean b ) throws SQLException
	{
		rawConnection.setAutoCommit( b );
	}

}